QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#489638 | #7815. 结构体 | EmsiaetKadosh | 0 | 0ms | 0kb | C++14 | 8.2kb | 2024-07-24 22:05:48 | 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