ccf刷题记03

来源:互联网 发布:国债收益率升高知乎 编辑:程序博客网 时间:2024/05/29 05:53

今年9月份的最新题,还是有必要做一下的,然而网上搜不到题解,就比较坑了,没事,没做出来的题等下次ccf之前再补吧,看这段时间自己又能长进多少

201709-1打酱油

思路:这题一开始看到还有点懵,但这个样例的说明也太给了了吧,直接把做法就给出来说,分类讨论,瞬间秒做;

其实根据数据范围完全可以模拟的,单为了锻炼自己的计算能力,还是推了一下公式,这个能力还是需要的,毕竟之后无论什么题目似乎如果能用公式都比模拟好

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>using namespace std;aconst int maxn = 1e5+10;int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        int sum = 0;        /*while(n>=50)        {            n -= 50;            sum += 7;        }*/        int p1 = n/50;        n %= 50;        sum += p1*7;        /*while(n>=30)        {            n -= 30;            sum += 4;        }*/        int p2 = n/30;        n %= 30;        sum += p2*4;        /*while(n>=10)        {            n -= 10;            sum += 1;        }*/        int p3 = n/10;        sum += p3;        printf("%d\n",sum);    }    return 0;}

201709-2公共钥匙盒

思路:这题给的是每个老师的上课时间,拆分转化为钥匙交接的记录,按时间进行模拟就好了,建立数据结构存储时间,然后注意一下排序的原则就好了

最后,注意一下,不仅需要数组记录每个位置的钥匙,还需要单开一个数组记录钥匙的位置便于跟踪,其他就没什么了,30min2题,还好

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>using namespace std;const int maxn = 2010;typedef struct EVENT{    bool borrow;    int id;    int time;}Event;Event e[maxn];int key[maxn];int keypos[maxn];bool cmp(const Event &a, const Event &b){    if(a.time<b.time)    {        return true;    }    else if(a.time==b.time)    {        if((!a.borrow)&&b.borrow)        {            return true;        }        else if((!a.borrow)&&(!b.borrow))        {            if(a.id<b.id)            {                return true;            }        }    }    return false;}int main(){    int n,k;    while(scanf("%d%d",&n,&k)!=EOF)    {        for(int i=1;i<=n;i++)        {            key[i] = i;            keypos[i] = i;        }        for(int i=0;i<k;i++)        {            int keyid,keytime,keylast;            scanf("%d%d%d",&keyid,&keytime,&keylast);            e[2*i].borrow = true;            e[2*i].id = keyid;            e[2*i].time = keytime;            e[2*i+1].borrow = false;            e[2*i+1].id = keyid;            e[2*i+1].time = keytime+keylast;        }        sort(e,e+2*k,cmp);        for(int i=0;i<2*k;i++)        {            if(e[i].borrow)            {                key[keypos[e[i].id]] = 0;                keypos[e[i].id] = 0;            }            else            {                for(int pos=1;pos<=n;pos++)                {                    if(key[pos]==0)                    {                        key[pos] = e[i].id;                        keypos[e[i].id] = pos;                        break;                    }                }            }        }        printf("%d",key[1]);        for(int i=2;i<=n;i++)        {            printf(" %d",key[i]);        }        printf("\n");    }    return 0;}

201709-3JSON查询

思路:这题完全是字符串处理问题,用惯了scanf和字符串数组的我,对cin和getline真心手足无措,研究了好长时间

不过,这题确实信息量有点大,而且入手点也特别多,像冒号,引号,逗号都可以作为处理对象,而且后来发现任意处理一个结果都是一样的

但刚碰到的时候,就会思路一片混乱,不易冷静

有时候,一步步慢慢检查要比一起写完反而不知道哪里错了要好,不过还是细心吧,不出错总归是好的

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>using namespace std;const int maxn = 1e5+10;map<string,string> json;bool iskey;string dealstring(string key,string s){    if(s.empty())    {        //cout << "empty " << endl;        return key;    }    int slen = s.size();    for(int i=0;i<slen;i++)    {        //cout << key <<"*"<<s[i]<<"*"<<iskey<< endl;        if(s[i] == ' ')        {            continue;        }        if(s[i] == '{')        {            //cout << "*3*" << endl;            json[key] = "OBJECT";            iskey = true;        }        else if(s[i] == '}')        {            int len = key.size();            int str;            for(str = len-1;str>=0;str--)            {                if(key[str] == '.')                {                    break;                }            }            if(str < 0)            {                key = "";            }            else            {                key = key.substr(0,str);            }        }        else if(s[i] == ',')        {            iskey = true;        }        else if(s[i] == ':')        {            iskey = false;        }        else if(s[i] == '"')        {            //cout << s[i]  << s[i+1]<< endl;            string nowstring;            bool di = false;            int j;            for(j=i+1;j<slen;j++)            {                if(s[j] == '\\')                {                    if(di)                    {                        di = false;                        nowstring += '\\';                    }                    else                    {                        di = true;                    }                }                else if(s[j] == '"')                {                    if(di)                    {                        di = false;                        nowstring += '"';                    }                    else                    {                        break;                    }                }                else                {                    nowstring += s[j];                }            }            if(iskey)            {                if(key=="")                {                    key = nowstring;                }                else                {                    key += '.' + nowstring;                }            }            else            {                //cout << key << "*" << endl;                json[key] = "STRING " + nowstring;                int len = key.size();                int str;                for(str = len-1;str>=0;str--)                {                    if(key[str] == '.')                    {                        break;                    }                }                if(str < 0)                {                    key = "";                }                else                {                    key = key.substr(0,str);                }            }            i = j;        }    }    return key;}int main(){    int n,m;    //cout << json["hello"] << "***" << endl;    /*if(json["hello"]=="")    {        cout << "***" << endl;    }*/    ios::sync_with_stdio(false);    while(cin >> n >> m)    {        /*char hh;        hh = getchar();        cout << "^"<<hh << endl;*/        string temp;        getline(cin,temp);        json.clear();        /*cin.clear();        cin.sync();*/        iskey = false;        string laststring = "";        while(n--)        {            getline(cin,temp);            //cout << n << "###" <<temp<< endl;            laststring = dealstring(laststring,temp);        }        while(m--)        {            //cout << m << "***" << endl;            getline(cin,temp);            if(json[temp] == "")            {                cout << "NOTEXIST" << endl;            }            else            {                cout << json[temp] << endl;            }        }    }    return 0;}/*10 5{"firstName": "John","lastName": "Smith","address": {"streetAddress": "2ndStreet","city": "NewYork","state": "NY"},"esc\\aped": "\"hello\""}firstNameaddressaddress.cityaddress.postalesc\aped*/

201709-4通信网络

思路:这一题乍一看,似乎不怎么困难,统计前驱和后继,对于每个点,其前驱的前驱必是其前驱,其后继的后继必是其后继,为了去重,用两个set处理吧

果然TLE了,虽然报的是WA,但根据时间发现应该是TLE的问题,只得到了可怜的30分

然而突然发现有向图set的速度似乎有点慢,而且双向边似乎要存两遍,处理两遍

于是,考虑退化,用最基础的数组存储,果然变快了,又过了一部分数据,得到50分了

于是,又想到数组和vector结合可以避免set,然而还是50分

然后似乎就真心没什么办法了,就50分吧,以后看看能不能拿满

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>#include <set>using namespace std;const int maxn = 1010;/*set <int> pre[maxn];set <int> nex[maxn];set <int> connect[maxn];int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=EOF)    {        for(int i=1;i<=n;i++)        {            connect[i].clear();            nex[i].clear();            pre[i].clear();            connect[i].insert(i);            pre[i].insert(i);            nex[i].insert(i);        }        while(m--)        {            int p,q;            scanf("%d%d",&p,&q);            set<int> :: iterator it;            for(it=pre[p].begin();it!=pre[p].end();it++)            {                pre[q].insert(*it);                nex[*it].insert(q);                connect[q].insert(*it);                connect[*it].insert(q);            }            for(it=nex[q].begin();it!=nex[q].end();it++)            {                nex[p].insert(*it);                pre[*it].insert(p);                connect[p].insert(*it);                connect[*it].insert(p);            }        }        int sum = 0;        for(int i=1;i<=n;i++)        {            if((int)(connect[i].size())==n)            {                sum++;            }        }        printf("%d\n",sum);    }    return 0;}*//*bool connect[maxn][maxn];int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=EOF)    {        memset(connect,false,sizeof(connect));        for(int i=1;i<=n;i++)        {            connect[i][i] = true;        }        while(m--)        {            int p,q;            scanf("%d%d",&p,&q);            for(int i=1;i<=n;i++)            {                if(connect[i][p])                {                    connect[i][q] = true;                }                if(connect[q][i])                {                    connect[p][i] = true;                }            }        }        int sum = 0;        for(int i=1;i<=n;i++)        {            int tempsum = 0;            for(int j=1;j<=n;j++)            {                if(connect[i][j]||connect[j][i])                {                    tempsum++;                }            }            if(tempsum == n)            {                sum++;            }        }        printf("%d\n",sum);    }    return 0;}*/vector <int> pre[maxn];vector <int> nex[maxn];bool connect[maxn][maxn];int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=EOF)    {        memset(connect,false,sizeof(connect));        for(int i=1;i<=n;i++)        {            connect[i][i] = true;            nex[i].clear();            pre[i].clear();            pre[i].push_back(i);            nex[i].push_back(i);        }        while(m--)        {            int p,q;            scanf("%d%d",&p,&q);            vector<int> :: iterator it;            for(it=pre[p].begin();it!=pre[p].end();it++)            {                if(!connect[*it][q])                {                    connect[*it][q] = true;                    pre[q].push_back(*it);                    nex[*it].push_back(q);                }            }            for(it=nex[q].begin();it!=nex[q].end();it++)            {                if(!connect[p][*it])                {                    connect[p][*it] = true;                    nex[p].push_back(*it);                    pre[*it].push_back(p);                }            }        }        int sum = 0;        for(int i=1;i<=n;i++)        {            int tempsum = 0;            for(int j=1;j<=n;j++)            {                if(connect[i][j]||connect[j][i])                {                    tempsum++;                }            }            if(tempsum == n)            {                sum++;            }        }        printf("%d\n",sum);    }    return 0;}


201709-5 除法

思路:最后一题,线段树题,然而我对于线段树还是比较茫然的,还是试试骗分吧

开始了骗分之路,首先,强行模拟吧,利用第一个条件l=r,由区间变单点

后来发现只是操作1区间变单点,于是改用树状数组

然而还是0分,猛然发现,结果可能超long long,于是20分到手
于是,想再做个遍历,说不定又能骗一点分呢

果然,50分到手,最终ccf400+,还行,看来有些时候,还是变换形态吧,加油,fighting

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <map>#include <cmath>#include <string>#include <queue>#include <stack>using namespace std;const int maxn = 1e5+10;long long a[maxn],c[maxn];int lowbit(int x)//对应管辖区域{return x&-x;}long long sum(int i)//求数组c前i项和{long long s=0;while(i>0){s+=c[i];i-=lowbit(i);}return s;}void modify(int i,long long val,int n)//将第i个元素加上val,n为数组大小{while(i<=n){c[i]+=val;i+=lowbit(i);}}int main(){    //cout<<"1"<<endl;    //cout<<"2"<<endl;    int n,m;    while(scanf("%d%d",&n,&m)!=EOF)    {        memset(c,0,sizeof(c));        for(int i=1;i<=n;i++)        {            scanf("%lld",&a[i]);            modify(i,a[i],n);        }        while(m--)        {            int p;            scanf("%d",&p);            if(p==1)            {                int l,r;                long long v;                scanf("%d%d%lld",&l,&r,&v);                //cout << l << "*"<< r << "*" << v << endl;                for(int i=l;i<=r;i++)                {                    //cout << "###" << endl;                    if(a[i]%v==0)                    {                        a[i] /= v;                        long long di = a[i] - a[i]*v;                        modify(i,di,n);                    }                    /*for(int j=1;j<=n;j++)                    {                        cout << sum(j) << " ";                    }                    cout << endl;*/                }            }            else            {                int l,r;                scanf("%d%d",&l,&r);                printf("%lld\n",sum(r) - sum(l-1));                /*for(int i=1;i<=n;i++)                {                    cout << sum(i) << " ";                }                cout << endl;*/            }        }    }    return 0;}

最后两题,这段时间确实是没时间再补了,以后有时间再看看吧


文章地址:http://blog.csdn.net/owen_q/article/details/78229956

原创粉丝点击