csp 202012-3

csp 202012-3

起因

又通知csp认证,可是这个好贵呀,刷一刷历年考题感觉第三题还有点意思,软件工程那种味道,不过我的算法水平也不怎样就是了.

经过

于是就卡在这个题上了.
最近看了一点操作系统就想试试.
过了两个样例,结果只有20分 xp
我加了一个print文件系统的函数,每一步操作之后把整个文件系统写入stderr,
结果,又整出几个bug,再继续,我又通过硬看代码,找出一个错误,提交之后,显示超时,我真是无话可说,来来去去看了几遍,找不到错误.
于是我又整了一个随机数据生成器,有用别人的100%代码,对比输出结果.

# datagen.py
from random import randint

def randname():
    return chr(randint(0,7)+ord('A'))+str(randint(0,5))

def randpath(low=1):
    n=randint(low,20)
    return '/'+'/'.join(randname() for i in range(n))

def randcmd():
    r=randint(0,2)
    if r==0:
        return 'C %s %d' % (randpath(1),randint(0,1e9))
    elif r==1:
        return 'R %s' % randpath(1)
    else:
        return 'Q %s %d %d' % (randpath(),randint(0,1e18),randint(0,1e18))

n=1000
print(n)
for i in range(n):
    print(randcmd())
%Makefile
all: cmp

regen:
	del rand.in
	make all

cmp: a.out o.out
	diff a.out o.out

a.out: rand.in a.exe
	a < rand.in > a.out 2> nul

o.out: rand.in o.exe
	o < rand.in > o.out 2> nul

a.exe: main.cpp
	cc main.cpp -o a

o.exe: others.cpp
	cc others.cpp -o o

rand.in: datagen.py
	python datagen.py > rand.in

clean:
	del *.exe rand.in a.out o.out

n=10整了好几次,就是那个一改就超时的地方,我怎么都想不出来哪里有死循环.

结果

直到我把n改成1000,结果好久都不出结果.
所以我终于知道了,是把时间浪费在IO上了.
于是我把那个函数tree去掉,结果就过了.
最后,

#include <bits/stdc++.h>

#define contains(a,b) ((a)->v.infoD.ch->find(b)!=(a)->v.infoD.ch->end())
#define get(a,b) ((*(a)->v.infoD.ch)[b])

using namespace std;

typedef long long ll;

struct File{
    
    
    enum{
    
    D,F}type;
    union{
    
    
        struct{
    
    
            ll ld,lr;
            ll sd,sr;
            string *name;
            map<string,File*> *ch;
        }infoD;
        struct{
    
    
            ll size;
            string *name;
        }infoF;
    }v;
};


File *newDir(const string& name) {
    
    
    return new File({
    
    
        File::D,
        {
    
    {
    
    0,0,0,0,
        new string(name),
        new map<string,File*>}}
    });
}

File *newFile(ll size,const string& name) {
    
    
    File *ret=new File;
    ret->type=File::F;
    ret->v.infoF.size=size;
    ret->v.infoF.name=new string(name);
    return ret;
}

File *fs=newDir("");

void tree(File *cur=fs,int n=0) {
    
    
    return;
    if(cur->type==File::F)cerr<<'F';
    else cerr<<'D';
    for(int i=0;i<n;++i)cerr<<'\t';
    if(cur->type==File::F){
    
    
        cerr<<*(cur->v.infoF.name)<<' '<<cur->v.infoF.size<<endl;
    }
    else{
    
    
        cerr<<*(cur->v.infoD.name)<<' '<<cur->v.infoD.sd<<' '<<cur->v.infoD.sr<<' '<<cur->v.infoD.ld<<' '<<cur->v.infoD.lr<<endl;
        for(auto i:*cur->v.infoD.ch){
    
    
            tree(i.second,n+1);
        }
    }
}

vector<string> dirs;
string name;

void split(const string& path){
    
    
    dirs.clear();
    char buf[101];
    int i=1,j=0;
    for(;i<path.size();++i){
    
    
        if(path[i]=='/'){
    
    
            buf[j]=0;
            j=0;
            dirs.push_back(buf);
        }
        else{
    
    
            buf[j++]=path[i];
        }
    }
    buf[j]=0;
    name=buf;
}

enum State{
    
    Filemet,Ffalse,Found,Notfound};
State tranverse(File *&cur,function<bool(File*,const string&)> f) {
    
    
    cur=fs;
    for(int i=0;i<dirs.size();++i){
    
    
        if(!f(cur,dirs[i]))return Ffalse;
        if(!contains(cur,dirs[i]))return Notfound;
        cur=get(cur,dirs[i]);
        if(cur->type==File::F)return Filemet;
    }
    return Found;
}

bool create(){
    
    
    string path;
    ll size,fsize=0;
    cin>>path>>size;
    split(path);
    File *cur=fs,*t,*tar;
    State st=tranverse(cur,[&](File *cur,const string& s)->bool{
    
    
        return true;
    });
    if(st==Filemet){
    
    cerr<<"can't create dir with the name same with file"<<endl;return false;}
    if(st==Found&&contains(cur,name)){
    
    
        tar=get(cur,name);
        if(tar->type==File::D){
    
    cerr<<"can't create file with the name same with dir"<<endl;return false;}
        else fsize=tar->v.infoF.size;
    }
    tranverse(cur,[&](File *cur,const string& s)->bool{
    
    
        if(cur->v.infoD.lr!=0&&cur->v.infoD.sr-fsize+size>cur->v.infoD.lr){
    
    cerr<<"lr exceeded"<<endl;return false;}//this ocationally right
        if(!contains(cur,s)){
    
    
            t=newDir(s);
            get(cur,s)=t;
        }
        return true;
    });
    if(cur->v.infoD.lr!=0&&cur->v.infoD.sr-fsize+size>cur->v.infoD.lr){
    
    cerr<<"lr exceeded"<<endl;return false;}
    if(cur->v.infoD.ld!=0&&cur->v.infoD.sd-fsize+size>cur->v.infoD.ld){
    
    cerr<<"ld exceeded"<<endl;return false;}
    tranverse(cur,[&](File *cur,const string& s)->bool{
    
    
        cur->v.infoD.sr+=-fsize+size;
        return true;
    });
    cur->v.infoD.sr+=-fsize+size;
    cur->v.infoD.sd+=-fsize+size;
    t=newFile(size,name);
    get(cur,name)=t;//memory leaking? never mind.
    return true;
}
bool remove(){
    
    
    string path;
    cin>>path;
    ll fsize=0;
    split(path);
    File *cur=fs,*tar;
    State st=tranverse(cur,[&](File *cur,const string& s)->bool{
    
    
        return true;
    });
    if(st==Notfound||st==Filemet)return true;
    if(contains(cur,name)){
    
    
        tar=get(cur,name);
        if(tar->type==File::D)fsize=tar->v.infoD.sr;
        else fsize=tar->v.infoF.size;
    }
    else return true;
    cur=fs;
    tranverse(cur,[&](File *cur,const string&)->bool{
    
    
        cur->v.infoD.sr+=-fsize;
        return true;
    });
    if(tar->type==File::F)cur->v.infoD.sd+=-fsize;
    cur->v.infoD.sr+=-fsize;
    cur->v.infoD.ch->erase(name);//memory leaking. never mind.
    return true;
}
bool query(){
    
    //?
    string path;
    ll ld,lr;
    File *cur=fs,*tar;
    cin>>path>>ld>>lr;
    split(path);
    State st=tranverse(cur,[&](File *cur,const string&)->bool{
    
    
        return true;
    });
    if(st==Notfound||st==Filemet)return false;
    if(contains(cur,name)){
    
    
        tar=get(cur,name);
        if(tar->type==File::F){
    
    cerr<<"not a directory"<<endl;return false;}
    }
    else if(cur==fs&&name=="")tar=fs;
    else {
    
    cerr<<"file not found"<<endl;return false;}
    if(lr!=0&&tar->v.infoD.sr>lr){
    
    cerr<<"lr exceeded"<<endl;return false;}
    if(ld!=0&&tar->v.infoD.sd>ld){
    
    cerr<<"ld exceeded"<<endl;return false;}
    tar->v.infoD.lr=lr;
    tar->v.infoD.ld=ld;
    return true;
}

int main(){
    
    
    //freopen("test3.in","r",stdin);
    int n;
    char c;
    cin>>n;
    bool state;
    for(int i=0;i<n;++i){
    
    
        cin>>c;
        cerr<<i<<"----------------"<<c<<endl;
        switch(c){
    
    
            case 'C':
                state=create();break;
            case 'R':
                state=remove();break;
            case 'Q':
                state=query();break;
        }
        cout<<(state?'Y':'N')<<endl;
        tree();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/agctXY/article/details/120072323
CSP