QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#489638#7815. 结构体EmsiaetKadosh0 0ms0kbC++148.2kb2024-07-24 22:05:482024-07-24 22:05:48

Judging History

你现在查看的是最新测评结果

  • [2024-07-24 22:05:48]
  • 评测
  • 测评结果:0
  • 用时:0ms
  • 内存:0kb
  • [2024-07-24 22:05:48]
  • 提交

answer


#include <iostream>
#include <list>
#include <map>

#define _STD ::std::

class Class;
class BaseType;

class Base {
public:
	int offset = -1;
	bool isBase = false;
	friend class Class;
	friend class BaseType;
	virtual void* alloc() const noexcept = 0;
	virtual void dealloc(void* ptr) const noexcept = 0;
	virtual int size() const noexcept = 0;
	virtual int align() const noexcept = 0;
	virtual void* create() const noexcept = 0;

	virtual ~Base() {}
};

struct BaseType : public Base {
	BaseType() { isBase = true; }
};

struct Byte : public BaseType {
	int size() const noexcept override { return 1; }

	int align() const noexcept override { return 1; }

	void* alloc() const noexcept override { return new char; }

	void dealloc(void* ptr) const noexcept override { delete (char*) ptr; }

	void* create() const noexcept override { return new Byte; }
};

struct Short : public BaseType {
	int size() const noexcept override { return 2; }

	int align() const noexcept override { return 2; }

	void* alloc() const noexcept override { return new short; }

	void dealloc(void* ptr) const noexcept override { delete (short*) ptr; }

	void* create() const noexcept override { return new Short; }
};

struct Int : public BaseType {
	int size() const noexcept override { return 4; }

	int align() const noexcept override { return 4; }

	void* alloc() const noexcept override { return new int; }

	void dealloc(void* ptr) const noexcept override { delete (int*) ptr; }

	void* create() const noexcept override { return new Int; }
};

struct Long : public BaseType {
	int size() const noexcept override { return 8; }

	int align() const noexcept override { return 8; }

	void* alloc() const noexcept override { return new long; }

	void dealloc(void* ptr) const noexcept override { delete (long*) ptr; }

	void* create() const noexcept override { return new Long; }
};

struct Codata {
	_STD map<_STD string, Base*> namedMembers;
	_STD list<Base*> members;
	int sizes = 0;
	int aligns = 0;
	int offsets = 0;
};

class Class : public Base {
	Codata* codata;
public:
	Class() { codata = new Codata; }

	Class(Codata* c) :
		codata{ c } {}

	~Class() override {
		for (auto iter = codata->members.begin(); iter != codata->members.end(); ++iter) delete iter.operator*();
	}

	void addMember(_STD string name, Base* member) {
		member = (Base*) member->create();
		if (member->align() > codata->aligns) {
			codata->aligns = member->align();
			codata->offsets = 0;
			for (auto iter = codata->members.begin(); iter != codata->members.end(); ++iter) {
				(*iter)->offset = codata->offsets;
				codata->offsets += ((*iter)->size() / codata->aligns + ((*iter)->align() % codata->aligns == 0 ? 0 : 1));
			}
		}
		member->offset = codata->offsets;
		codata->offsets += (member->size() / codata->aligns + (member->align() % codata->aligns == 0 ? 0 : 1));
		codata->sizes = codata->offsets * codata->aligns;

		codata->members.push_back(member);
		codata->namedMembers.insert(_STD make_pair(name, member));
	}

	void* getMember(_STD string name, void* ptr, int& align) const {
		int p = name.find_first_of('.');
		align = codata->aligns;
		if (p == _STD string::npos) return ((char*) ptr) + (codata->namedMembers.at(name)->offset * codata->aligns);
		else {
			Class* k = ((Class*) codata->namedMembers.at(name.substr(0, p)));
			return k->getMember(name.substr(p + 1), ((char*) ptr) + (k->offset * codata->aligns), align);
		}
	}

	void* ptrof(void* src, int off, int& align) const noexcept {
		if (off > codata->sizes) return nullptr;
		align = codata->aligns;
 // offset未必遵循aligns
		for (auto iter = codata->members.begin(); iter != codata->members.end(); ++iter) {
			if ((*iter)->offset * codata->aligns == off) {
				if ((*iter)->isBase)
					return ((char*) src) + off;
				else
					return ((Class*) *iter)->ptrof(((char*) src) + off, 0, align);
			} else if ((*iter)->offset * codata->aligns > off) {
				if (iter == codata->members.begin())
					return nullptr;
				else if ((*--iter)->isBase)
					return nullptr;
				else {
					return ((Class*) *iter++)->ptrof(((char*) src + (*iter)->offset * codata->aligns), offset - (*iter)->offset * codata->aligns, align);
				}
			}
		}
 // 比最后一个还大一点
		if (codata->members.back()->offset * codata->aligns == off)
			return ((char*) src) + off;
		else
			return nullptr;
	}

	int size() const noexcept override { return codata->sizes; }

	int align() const noexcept override { return codata->aligns; }

	void* alloc() const noexcept override { return malloc(codata->sizes); }

	void dealloc(void* ptr) const noexcept override { free(ptr); }

	void* create() const noexcept override { return new Class(codata); }
};

struct ClassRegistry {
	_STD map<_STD string, Base*> registry;

	ClassRegistry() {
		registry.insert(_STD make_pair("byte", new Byte));
		registry.insert(_STD make_pair("short", new Short));
		registry.insert(_STD make_pair("int", new Int));
		registry.insert(_STD make_pair("long", new Long));
	}

	~ClassRegistry() {
		for (auto iter = registry.begin(); iter != registry.end(); ++iter) delete iter.operator*().second;
	}
} classes;

struct Instance {
	Base* type;
	void* value;

	Instance(Base* type) {
		value = type->alloc();
	}

	~Instance() {
		type->dealloc(value);
	}
};

struct InstanceRegistry {
	_STD map<_STD string, Instance*> registry;
	_STD list<Instance*> instances;
	int size = 0;

	~InstanceRegistry() {
		for (auto iter = instances.begin(); iter != instances.end(); ++iter) delete iter.operator*();
	}

	void* getMember(_STD string name, int& align) {
		align = 0;
		int p = name.find_first_of('.');
		Instance* i = registry.at(name.substr(0, p));
		return ((Class*) i->type)->getMember(name.substr(p + 1), i->value, align);
	}

	int reg(_STD string name, Instance* instance) noexcept {
		registry.insert(_STD make_pair(name, instance));
		instances.push_back(instance);
		instance->type->offset = size;
		size += instance->type->size();
		return instance->type->offset;
	}

	void* ptrof(int off, int& align) noexcept {
		for (auto iter = instances.begin(); iter != instances.end(); ++iter) {
			if ((*iter)->type->offset == off) return (*iter)->value;
			else if ((*iter)->type->offset > off) {
				--iter;
				if (iter.operator*()->type->isBase)
					return nullptr;
				else
					return ((Class*) iter.operator*()->type)->ptrof(((char*) iter.operator*()->value), off - iter.operator*()->type->offset, align);
			}
		}
		return nullptr;
	}
} instances;

int main() {
	int count;
	int pos;
	_STD cin >> count;
	_STD string temp;
	_STD string name;
	for (int i = 0; i < count; i++) {
		_STD cin >> temp;
		switch (temp.at(0)) {
			case '1': {
				_STD cin >> name;
				_STD cin >> temp;
				Class* klass = new Class();
				classes.registry.insert(_STD make_pair(name, klass));
				int t = atoi(temp.c_str());
				for (int j = 0; j < t; ++j) {
					_STD cin >> name;
					_STD cin >> temp;
					klass->addMember(temp, classes.registry.at(name));
				}
				_STD cout << klass->size() << ' ' << klass->align() << _STD endl;
			} break;
			case '2': {
				_STD cin >> name;
				_STD cin >> temp;
				Instance* instance = new Instance(classes.registry.at(name));
				_STD cout << instances.reg(temp, instance) << _STD endl;
			} break;
			case '3': {
				_STD cin >> temp;
				int align = 0;
				void* ptr = instances.getMember(temp, align);
				if (ptr == nullptr) {
					_STD cout << "ERR\n";
					continue;
				}
				switch (align) {
					case 1:
						_STD cout << (int) *(char*) ptr;
					case 2:
						_STD cout << *(short*) ptr;
					case 4:
						_STD cout << *(int*) ptr;
					case 8:
						_STD cout << *(long*) ptr;
				}
			} break;
			case '4': {
				_STD cin >> temp;
				int align = 0;
				void* ptr = instances.ptrof(atoi(temp.c_str()), align);
				if (ptr == nullptr) {
					_STD cout << "ERR\n";
					continue;
				}
				switch (align) {
					case 1:
						_STD cout << (int) *(char*) ptr;
					case 2:
						_STD cout << *(short*) ptr;
					case 4:
						_STD cout << *(int*) ptr;
					case 8:
						_STD cout << *(long*) ptr;
				}
			} break;
		}
	}
}

Details

Tip: Click on the bar to expand more detailed information

Pretests


Final Tests

Test #1:

score: 0
Runtime Error

input:

93
2 long gkwc
3 gkwc
2 long omvjdthb
4 1
2 long cumx
3 omvjdthb
4 16
3 gkwc
2 long tebdginn
4 15
4 30
3 omvjdthb
4 22
4 37
2 long nbghbbahln
2 long kkjzl
4 9
3 nbghbbahln
4 31
3 nbghbbahln
3 gkwc
2 long hjzfa
2 long tptemwur
4 39
3 tptemwur
2 long sjybn
4 8
4 15
3 cumx
2 long xathyrnc
4 32
3 xathyr...

output:


result:


Test #2:

score: 0
Runtime Error

input:

100
4 0
4 4
2 byte szqir
2 long fweahddll
2 byte dvqu
3 szqir
2 long wqcnqxppvg
3 szqir
4 9
4 33
3 wqcnqxppvg
4 38
4 5
4 33
2 short erhxh
2 short wwsp
4 3
3 szqir
4 42
2 short pxkwnp
4 15
2 int teuwwrw
4 45
3 erhxh
2 int uuycypz
3 uuycypz
4 48
4 35
4 6
3 wqcnqxppvg
2 byte yvgc
3 yvgc
3 teuwwrw
4 25
...

output:

ERR
ERR

result:


Test #3:

score: 0
Runtime Error

input:

99
2 long mrbfn
4 1
3 mrbfn
3 mrbfn
3 mrbfn
3 mrbfn
2 byte oosmberlsb
3 mrbfn
3 oosmberlsb
2 byte auhmoewi
4 7
4 3
2 long jplopgx
4 0
4 31
2 int qqgjpu
2 long plfawkhtd
3 auhmoewi
3 plfawkhtd
2 int uwue
2 long muvlnlgqn
4 46
4 46
4 22
2 long inhosie
3 auhmoewi
3 oosmberlsb
2 byte pziz
2 byte anyxdru...

output:


result:


Test #4:

score: 0
Runtime Error

input:

99
1 lfqikjtpgg 97
long mbtn
long snpj
long fqb
long vdnkbv
long zqqjxhrj
long upp
long oe
long lv
long sea
long a
long fdymaqnuy
long oyshjkhm
long secuap
long o
long uvq
long xpw
long fsytmbpaaw
long rx
long nhmski
long hzop
long noy
long mqbitjlx
long jewquyks
long auntk
long ak
long bsksgoi
long...

output:

776 8

result:


Test #5:

score: 0
Runtime Error

input:

92
1 stmyil 94
long frzkeaq
long uloz
long khxrakhvl
long mgmigozwpb
long gcmzgib
long tktaj
long ttgattk
long ugnfjyqjei
long qqihkphedp
long jps
long bhdunqh
long qsefx
long iujkjmuolx
long lpyffp
long qryknjg
long utrepva
long dsmu
long qxazh
long nc
long u
long lzslpheclz
long ftjm
long chwf
lon...

output:

752 8

result:


Test #6:

score: 0
Runtime Error

input:

98
1 mmozfzqkeq 98
byte snth
short p
short ukfuxuar
byte vidqzvet
short mtzfq
byte umfo
short rxzppsvp
short jkcngxzj
byte upvqni
short wnthhncby
byte zzwunbs
short hsmgblo
short ccgvhtx
byte wmru
byte gfhcr
short fwfanwrr
byte wyhihbma
byte rppirq
short nspggyr
short wkntvbwwlv
byte hoqqz
byte fvcn...

output:

196 2

result:


Test #7:

score: 0
Runtime Error

input:

92
1 xreiqsyjsl 94
int joqtxmb
byte eobzfc
int yglime
int ghhoizgeq
long kiza
long aef
int ahkehlz
byte kgzpv
long nf
byte hmshwxalu
short tniregati
byte m
short ybauqfo
byte tmtnxog
int etgavrbmqj
short mdirp
int qofuzp
int lzyvpl
int tfdwv
int obskuccugg
byte bgq
short ze
long bpyzngywya
int rcyis...

output:

752 8

result:


Test #8:

score: 0
Runtime Error

input:

93
1 spkif 90
short klz
short wlbylhewfp
short kyaoz
byte iuszpejqeb
short hlbbgkvnhn
short xwsavtujm
byte pgfwluu
byte mbsh
short ybzxrav
short ilmd
short dvntuiawh
short ucbdcgwkyr
short m
byte qefbom
short rpdiishks
short dbq
byte amiipjf
short rcuw
byte ct
short brdieyded
short snuehuwrbf
byte o...

output:

180 2

result:


Test #9:

score: 0
Runtime Error

input:

100
1 tmwddcqr 96
long vc
long bzjxjo
long rpfgxjw
long rwfnwjxezo
long evovfc
long gj
long zwoml
long qtgongwrsf
long qoti
long xoisdmvl
long vkcbsjti
long lyv
long ipjvh
long lmemkym
long zybinjoacb
long xo
long opaxv
long fd
long cheprbq
long vwmixkoa
long qkxjkn
long ty
long ad
long nrrm
long kl...

output:

768 8
800 8
640 8
112 8
736 8
200 8
760 8
776 8
424 8
784 8
ERR
ERR

result:


Test #10:

score: 0
Runtime Error

input:

94
1 oeareonbmc 94
long sjlbu
long ddjtxqy
long ac
long rjmwvryp
long bjw
long kjxs
long dns
long wycl
long scucpcfki
long vhotgxwf
long yfgvgw
long xb
long um
long cmcuihmv
long jwyuguj
long dl
long hgecyw
long cn
long xrwhhsqoar
long xfajrvvuy
long pg
long ln
long bwgziqt
long knwn
long mjmz
long ...

output:

752 8
776 8
672 8
720 8
760 8
536 8
760 8
632 8
776 8
760 8
ERR

result:


Test #11:

score: 0
Runtime Error

input:

100
1 qg 75
short imvphecx
long tgthzzocgy
int z
long rdkrbwqi
long bkzeqx
byte ebcxwfjeka
long ugvjxbayyc
int srjda
long ah
short nhqbw
int twpca
byte hynzjak
long mwrjaitjf
byte qeensxo
short oc
int pniisvwlr
int yvqoaipq
long nwokprd
long pryksxsjti
byte zhbuomugxl
int bgk
byte luo
byte kmimxmj
b...

output:

600 8
656 8
736 8
768 8
192 2
752 8
792 8
800 8
744 8
496 8
728 8

result:


Test #12:

score: 0
Runtime Error

input:

98
1 prjerge 52
short baiklk
short pdauxtmhcs
long bmutcn
long xhrktulr
short gxqgh
short ylxevjych
short rgd
byte gixpucez
int bbmq
byte giezc
short goonshi
byte pupsmxs
int jmadko
byte lziz
short azfctnm
long pxlp
int lcezuwix
int pwcmndzare
int isjkucax
int tngygloe
int vjcs
int dbcsddgz
short ct...

output:

416 8
752 8
608 8
122 2
61 1
194 2
372 4
416 8
720 8
752 8

result:


Test #13:

score: 0
Runtime Error

input:

95
1 icyrswqfl 93
short qffx
byte lkojhr
long hhsbxdps
long gcsi
long hiznsou
short hjwpmzywv
int hhxyuk
byte vrudbiwl
byte cqmcxfx
long jzdrah
int uafucqu
int gwixgsyfa
short ezyti
long iczdyjxa
short tc
short vyvozoirs
long m
int kpmg
short ecxfhjhfu
short gwdqiiza
int yfjmrewujt
int hl
long t
lon...

output:

744 8
800 8
464 8
768 8
188 2
512 8
792 8
736 8
568 8
736 8

result:


Test #14:

score: 0
Runtime Error

input:

93
1 rrcruvb 100
long gbrpkh
long o
long npx
long fqbwyv
long cer
long xtmxwgset
long slohh
long r
long kkljaga
long wkesor
long belhrmxthz
long bw
long vx
long wfqc
long nqdvlk
long v
long mlgm
long hioyoss
long rhpyhqr
long troazjcq
long got
long mxkp
long nwayf
long qofxrrhp
long ttskfndao
long j...

output:

800 8
648 8
728 8
144 8
696 8
696 8
248 8
800 8
776 8
776 8
51168 8
ERR
30960 8

result:


Test #15:

score: 0
Runtime Error

input:

92
1 mfqfaoi 51
long vgiijn
long kqvmcutd
long kkqmfdmdsg
long we
long h
long lx
long bdzy
long tqb
long ayybs
long iefznflod
long qjw
long xq
long hajgbfpuqj
long otlrrbqpy
long xpxyro
long lum
long umizkapzp
long jxjjgsuab
long aesd
long redlyai
long htpfoi
long eyo
long hkc
long hb
long wwt
long ...

output:

408 8
512 8
752 8
736 8
744 8
408 8
736 8
664 8
768 8
792 8

result:


Test #16:

score: 0
Runtime Error

input:

92
1 itmex 54
long qlmtjv
long eoiw
long ef
long imfhgcc
long cvvwlhqj
long pwrrrcarid
long ejs
long v
long cjl
long qfhsxdx
long opqhk
long rtyfmpb
long cgefjpnsyj
long oaovfhc
long vun
long thwqf
long hhdrhsizr
long ckwl
long gaxdzp
long mwcw
long knjp
long zcemzmfs
long zlnjmriio
long oein
long s...

output:

432 8
696 8
784 8
448 8
800 8
536 8
760 8
760 8
256 8
720 8
ERR

result:


Test #17:

score: 0
Runtime Error

input:

94
1 gzvgm 96
int ozzmlzdcs
short lzf
int tc
int cpagll
byte jktmts
long qtsyn
long rfyehp
int dmfpk
byte dourj
byte aoqijd
short er
int aykwg
byte bozawefpt
short kodpn
short lk
byte xxem
byte cvo
long vdowzxhn
short rutrrcfua
short wev
short wnkufo
byte hvo
int ovnbmuq
long rcx
short ngtdtdxt
byte...

output:

768 8
74 1
320 8
140 2
744 8
736 8
332 4
640 8
784 8
91 1
ERR

result:


Test #18:

score: 0
Runtime Error

input:

92
1 pyrj 59
short qjazriblv
int udo
long ifisemk
int inso
byte lpmnuevtab
int ilrtum
byte aucf
byte qvwxbxcevi
long sxboxvu
byte rjfpvq
byte iteamtvj
int lrsf
short nnbnd
long ndiwpi
short hvcpdhh
short rqmusonxma
short agoriisqdu
short jqskvkw
short qyq
long zvmpxd
byte mbb
long kpabhzk
int qktde
...

output:

472 8
91 1
544 8
744 8
182 2
760 8
552 8
720 8
752 8
99 1

result:


Test #19:

score: 0
Runtime Error

input:

100
1 deam 92
int puxuhin
byte qzbt
byte oelfvt
short qjhpt
short zvmv
byte hmdzptx
long mctwgosxff
short uygqtcthn
long ykshnocnt
int ybsvabraeu
int qzwh
long brrtu
byte fide
byte lisonhykl
short pmsend
byte dhqyw
short rso
long vmuhoz
byte kasnh
long lyjjfblrb
short uzsagojr
byte odqcqtjcvs
byte m...

output:

736 8
52 4
292 4
784 8
800 8
696 8
768 8
28 4
680 8
792 8
ERR

result:


Test #20:

score: 0
Runtime Error

input:

100
1 vmtrvlmprp 99
byte hbvh
long ifeouvbu
long ylh
long hqgw
int wcs
short oavgeme
byte ppmssx
byte prdykjzgw
byte obta
short yzf
byte ozqfbozj
short vuypsqhd
byte anwbcc
byte iiungtbs
short dkhape
byte ixh
short gbdm
long ijrczrv
short rgkc
short amskm
short jguttrfv
short dotlif
byte tqvwccaafx
...

output:

792 8
67 1
728 8
368 4
24 8
182 2
784 8
372 4
512 8
800 8
ERR
26984 8
16900 4
ERR
241328 8
ERR

result: