zoukankan      html  css  js  c++  java
  • 18.4.1 考试解题报告 P71

    题目:https://files.cnblogs.com/files/lovewhy/problem.pdf

    偷偷摘来dalao题面。

    P71
    竞赛时间:???? 年?? 月?? 日??:??-??:??

     题目名称 智乃   麻耶 惠 
     名称  kahuucino  zyougamaya nacumegu 
    输入   kahuucino.in  zyougamaya.in nacumegu.in 
    输出   kahuucino.out   zyougamaya.out nacumegu.out 
    每个测试点时限   1秒  1秒 1秒 
    内存限制  512MB   512MB  512MB
    测试点数目   20  10 10 
    每个测试点分值  10  10 
    是否有部分分   无  无 无 
    题目类型   传统 传统  传统 

                  

    T1

                              智乃
    【题目描述】
        给你N个字符串,你每次可以选择其中一个字符串的一段前缀进行翻转,但是你必须保证这个前缀的长度是偶数。你可以进行无限次这样的操作,并且如果
        两个字符串变得相同的时候,你就可以把这两个字符串都删除掉,问最后最少剩下多少个字符串?
    【输入格式】
        第一行一个整数T代表数据组数。
        对于每组数据,第一行一个整数N代表字符串个数。
        接下来N行每行一个字符串。
    【输出格式】
        对于每组数据,一行一个整数代表答案。
    【样例输入】
      2
      5
      esprit
      god
      redotopc
      odcpoter
      dog
      14
      rats
      live
      stressed
      to
      act
      as
      star
      desserts
      of
      evil
      cat
      sa
      fo
      ot
    【样例输出】
      3
      0
    【样例解释】
      无。
    【数据范围与规定】
      40%的数据,字符串长度不超过8。
      对于100%的数据,1 ≤ T≤ 11,字符串长度不超过50,1 ≤ N ≤ 50。

    T1

    考场40分暴力:

       开个结构体存字符串,然后bfs里暴力翻转,set判重,记录下来,最后n^4判断能不能消除。

       前40分字符串长度<=8,翻转之后貌似是最多有384个串。

    //T1
    //这么难的吗???
    //........
    //暴力搞来一发
    //1hour left
    //i am so nervous 
    
    //不会写hash啊。。。老写炸。。
    //那怎么判重啊/。。。
    //Meide 
    //trie树?
    //hhhh gg 
    
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<set>
    using namespace std;
    
    const int N=55;
    
    int T,n;
    struct STR
    {
        bool flag;
        int len;
        int sum;
        string s;
        string ss[1000];
    }str[N];
    
    inline int read()
    {
        char c=getchar();int num=0,f=1;
        for(;!isdigit(c);c=getchar())
            f=c=='-'?-1:f;
        for(;isdigit(c);c=getchar())
            num=num*10+c-'0';
        return num*f;
    }
    
    inline void mswap(char &a,char &b)
    {
        char c=a;
        a=b;
        b=c;
    }
    
    inline string reverse(string s,int a,int b)        //stl的reverse不会用。。 
    {
        string tmp=s;
        for(;a<=b;++a,--b)
        {
            mswap(tmp[a],tmp[b]);
        }
    //    cout<<"tmp: "<<tmp<<endl;
        return tmp;
    }
    
    set<string> ma;
    queue<string> que;
    void bfs(STR &A)
    {
        ma.clear();
        ma.insert(A.s);
        que.push(A.s);
        string now,tmp;
        int len=A.len;
        while(!que.empty())
        {
            now=que.front();
    //        cout<<now<<endl;
            que.pop();
            for(int i=2;i<=len;++++i)
            {
                tmp=reverse(now,0,i-1);
                if(ma.count(tmp))
                    continue;
                que.push(tmp);
                A.ss[++A.sum]=tmp;
                ma.insert(tmp);
            }
        }
    }
    
    int main()
    {
        freopen("kahuucino.in","r",stdin);
        freopen("kahuucino.out","w",stdout);
        T=read();
        while(T--)
        {
            n=read();
            int ans=n;
            for(int i=1;i<=n;++i)
                str[i].flag=str[i].sum=0;
            for(int i=1;i<=n;++i)
            {
                cin>>str[i].s;
    //            cout<<"aa: "<<str[i].s<<endl;
                str[i].ss[++str[i].sum]=str[i].s;
                str[i].len=str[i].s.length();
                bfs(str[i]);
            }
            bool flag;
    //        printf("%d",str[1].sum);
            for(int i=1;i<=n;++i)
            {
                if(str[i].flag)
                    continue;
                for(int j=i+1;j<=n;++j)
                {
                    if(str[j].flag||str[i].len!=str[j].len)
                        continue;
                    flag=0;
                    for(int k=1;k<=str[i].sum;++k)
                    {
                        for(int l=1;l<=str[j].sum;++l)
                        {
                            if(str[i].ss[k]==str[j].ss[l])
                            {
                                flag=1;
                                str[i].flag=str[j].flag=1;
                                ----ans;
                                break;
                            }
                        }
                        if(flag)
                            break;
                    }
                    if(flag)
                        break;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    40分暴力
    // luogu-judger-enable-o2
    //T1 正解
    //为什么这么6的呢
    //stl好用又简洁 
    //...代码真短 
    
    //因为不管怎么翻转,原串中挨着的两个字符第i和i+1个总挨在一起
    //所以我们把原串分解成很多两个字母的组合
    //让组合中的第一个字符的字典序<=第二个字符
    //然后,把这好几个组合按字典序排序
    //再把它们按排完序后的顺序组合起来
    //set判断
    //如果这个字符串以前出现过,那么就消掉,余下的字符串数量-2
    //否则就扔进set里
    
    //貌似好简单的对吧 
    //但是为什么就想不到呢
    //只想着打暴力了
    //想也不定能想出来 
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<vector>
    using namespace std;
    
    const int N=55;
    
    int T,n;
    set<string> se;
    string S[N];
    string s[N];
    string tmp;
    
    inline int work()
    {
        int len,ans=n;
        se.clear();
        for(int i=1;i<=n;++i)
        {
            len=S[i].length();
            for(int j=0;j*2<len;++j)
            {
                char x=S[i][j<<1],y=S[i][j<<1|1];
                if(x>y)
                    swap(x,y);
                s[j]=x,s[j]+=y;
            }
            sort(s,s+len/2);
            tmp.clear();
            for(int j=0;j<len/2;++j)
                tmp+=s[j];
            if(len&1)
                tmp+=S[i][len-1];
            if(se.count(tmp))
            {
                se.erase(tmp);
                ----ans;
            }
            else
                se.insert(tmp);
        }
        return ans;
    }
    
    string a;
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;++i)
                cin>>S[i];
            printf("%d
    ",work());
        }
        return 0;
    }
    正解

     麻耶


    【问题描述】
        油库里是幻想乡特有的一种生物。每只油库里都有一个战斗力值和一个能量值。当两只油库里战斗时,总是战斗力值高的一位获胜。获胜者的战斗力值将变
        成(自己的原战斗力值-对手的战斗力值+对手的能量值)。败者将死去。若两者战斗力值一样,则同归于尽。
        思考熊发现了很多油库里,他想知道通过互相战斗之后油库里中战斗力值+能量值最高的一个可能到达多少。你能帮他们求出来吗?(假设除了考察的那只
        油库里之外,其他油库里之间不会发生战斗)
    【输入格式】
        第一行是一个整数N,代表当前有多少油库里。
        接下来的N行, 每一行有两个整数u,v, 代表这只油库里的战斗力值和能量值。
    【输出格式】
        输出一个整数,代表油库里中战斗力值+能量值最高的一个能达到多少。
    【样例输入】
      2
      1 2
      2 1
    【样例输出】
      4
    【样例解释】
      无。
    【数据规模与约定】

    数据点编号 N = 数据点编号 N =
    1 2 6 14989
    2 984 7 21726
    3 6168 8 100000
    4 10470 9 100000
    5 19168 10 100000

    T2

     理解错题意,那些油库里不一定要死。十分。。。也很多吧。

      天气炎热,不想改题。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    const int N=1e5+5;
    
    int n;
    long long ans,sum;
    struct Yuk
    {
        int u,v;
        bool operator < (const Yuk &a) const
        {
            return this->u==a.u?this->v>a.v:this->u<a.u;
        }
    }yuk[N];
    
    inline int read()
    {
        char c=getchar();int num=0,f=1;
        for(;!isdigit(c);c=getchar());
            f=c=='-'?-1:f;
        for(;isdigit(c);c=getchar())
            num=num*10+c-'0';
        return num*f;
    }
    
    int main()
    {
        n=read();
        for(int i=1;i<=n;++i)
        {
            yuk[i].u=read(),yuk[i].v=read();
        }
        sort(yuk+1,yuk+n+1);
        for(int i=1;i<=n;++i)
        {
            ans=max(ans,sum+yuk[i].u+yuk[i].v);
            if(yuk[i].u<yuk[i].v)
                sum+=yuk[i].v-yuk[i].u;
        }
        printf("%lld",ans);
        return 0;
    }
    View Code


    【问题描述】
        现在你要实现一个文件系统,支持以下操作
          cd Directory_Name
          如果当前路径下有名为 Directory_Name 的文件夹,则进入该文件夹所对应的路径,否则输出“No such directory!” 。
          cd ..
          如果当前路径存在父路径, 则返回父路径, 否则输出 “No parent directory!” 。
          touch File_Name
          如果当前目录下存在名为 File_Name 的文件则输出“File already exists!” ,否则创建这样一个文件。
          rm File_Name
          如果当前目录下存在名为 File_Name 的文件则删除它,否则输出“No suchfile!” 。
          mkdir Directory_Nam e
          如果在当前路径下存在名为 Directory_Name 的文件夹,则输出“Directoryalready exists!” ,否则创建这样一个文件夹(当前路径不变) 。
          rmdir Directory_Name
          如果在当前路径下存在名为 Directory_Name 的文件夹,则删除之,否则输出“No such directory!” 。
          ls
          列出当前路径下所有的文件和文件夹,每一项占一行,按创建的先后顺序给出。采用以下形式输:
            “Item_Name Type”    (Type 为 <D>(文件夹)或<F>(文件))
        注意:同一路径下文件与文件夹可以同名,但同一路径下文件与文件、文件夹与文件夹不能同名。
        初始时当前路径处于根路径下,无父路径。

    【输入格式】
        第一行为Q,表示有Q个操作。
        接下来是Q行,每行输入为以上描述的操作之一。

    【输出格式】
        输出答案。
    【样例输入】
      3
      mkdir standy
      touch totalfrank
      ls
    【样例输出】
      standy <D>
      totalfrank <F>
    【样例解释】
      无。
    【数据规模与约定】
      对于100%的数据,1 ≤ Q ≤ 100,所有文件名字长度不超过200且均为小写字母。

    T3

     模拟

    //耗我两个半小时。。made
    //写麻烦了,可以不开队列直接搞的
    //没时间改了。。
    //万一TLE
    //那就很TM了吧 
    
    //跑得真慢
    //样例都这么慢
    //等着翻车
    //别翻车啊... 
    
    //竟然A了。。。
    //又长又丑的代码 
    //懒得改它了。 
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<string>
    #include<stack>
    #include<queue>
    using namespace std;
    
    const int N=505;
    
    int Q;
    struct F
    {
        bool flag;
        int tim;
        string name;
    }file[N];
    struct D
    {
        bool flag;  //这个文件夹还在不在 
        int tim;    //文件夹创建时间 
        string name;    //文件夹名字 
        D *fa;        //父亲path 
        D *wjj[N];        //sons
        F *wj[N];    //file postions
        int s1,s2;    //sum of dires and files
        D *q1[N];
        F *q2[N];
        int h1,h2,t1,t2;
    }dir[N<<1],Root;
    
    typedef D* W;
    W null,now_d,now;
    string opt,name;
    
    typedef F* H;
    H now_f;
    
    inline void init()
    {
        now_f=file;
        now_d=dir;
        now=&Root;
        now->h1=now->h2=1;
        now->t1=now->t2=0;
        now->fa=null;
        now->flag=1;
        now->name="Root";
    }
    
    bool flag=0;
    W t1;
    H t2;
    int main()
    {
        freopen("nacumegu.in","r",stdin);
        freopen("nacumegu.out","w",stdout);
        init();
        scanf("%d",&Q);
        for(int i=1;i<=Q;++i)
        {
            cin>>opt;
    //        cout<<opt<<endl;
            if(opt=="ls")
            {
    //            cout<<now->t1<<" "<<now->t2<<endl;
    //            cout<<now->h1<<" "<<now->h2<<endl;
                while(1)
                {
                    if(now->h1>now->t1||now->h2>now->t2)
                        break;
                    t1=now->q1[now->h1],t2=now->q2[now->h2];
                    if(t1->flag==0)
                    {
                        ++(now->h1);
                        continue;
                    }
                    else if(t2->flag==0)
                    {
                        ++(now->h2);
                        continue;
                    }
                    if(t1->tim<t2->tim)
                    {
                        cout<<t1->name<<" <D>"<<'
    ';
                        ++(now->h1);
                    }
                    else
                    {
                        cout<<t2->name<<" <F>"<<'
    ';
                        ++(now->h2);
                    }
                }
                while(now->h1<=now->t1)
                {
                    t1=now->q1[now->h1];
                    if(!t1->flag)
                    {
                        ++(now->h1);
                        continue;
                    }
    //                printf("%s <D>
    ",now->q1[now->h1]->name);
                    cout<<t1->name<<" <D>"<<'
    ';
                    ++(now->h1);
                }
                while(now->h2<=now->t2)
                {
                    t2=now->q2[now->h2];
                    if(!t2->flag)
                    {
                        ++(now->h2);
                        continue;
                    }
    //                printf("%s <F>
    ",now->q2[now->h2]->name);
                    cout<<t2->name<<" <F>"<<'
    ';
                    ++(now->h2);
                }
                now->h1=now->h2=1;
                continue;
            }
            cin>>name;
    //        cout<<opt<<" "<<name<<endl;
            if(opt=="cd")
            {
                if(name=="..")
                {
                    if(now->fa==null)
                        puts("No parent directory!");
                    else
                        now=now->fa;
                }
                else
                {
                    flag=0;
                    for(int j=1;j<=now->s1;++j)
                    {
                        if(now->wjj[j]->flag&&now->wjj[j]->name==name)
                        {
                            now=now->wjj[j];
                            flag=1;
                            break;
                        }
                    }
                    if(!flag)
                        puts("No such directory!");
                }
            }
            else if(opt=="touch")
            {
                flag=0;
                for(int j=1;j<=now->s2;++j)
                {
                    if(now->wj[j]->flag&&now->wj[j]->name==name)
                    {
                        flag=1;
                        break;
                    }
                }
                if(!flag)
                {
                    ++now_f;
                    now_f->flag=1;
                    now_f->tim=i;
                    now_f->name=name;
                    now->wj[++now->s2]=now_f;
                    now->q2[++now->t2]=now_f;
                }
                else
                    puts("File already exists!");
            }
            else if(opt=="rm")
            {
                flag=0;
                for(int j=1;j<=now->s2;++j)
                {
                    if(now->wj[j]->flag&&now->wj[j]->name==name)
                    {
                        flag=1;
                        now->wj[j]->flag=0;
                        now->wj[j]->name="";
                        break;
                    }
                }
                if(!flag)
                    puts("No such file!");
            }
            else if(opt=="mkdir")
            {
                flag=0;
                for(int j=1;j<=now->s1;++j)
                {
                    if(now->wjj[j]->flag&&now->wjj[j]->name==name)
                    {
                        flag=1;
                        break;
                    }
                }
                if(flag)
                    puts("Directory already exists!");
                else
                {
                    ++now_d;
                    now_d->tim=i;
                    now_d->fa=now;
                    now_d->name=name;
                    now_d->flag=1;
                    now_d->h1=now_d->h2=1;
                    now_d->t1=now_d->t2=0;
                    now->wjj[++now->s1]=now_d;
                    now->q1[++now->t1]=now_d;
                }
            }
            else if(opt=="rmdir")
            {
                flag=0;
                for(int j=1;j<=now->s1;++j)
                {
                    if(now->wjj[j]->flag&&now->wjj[j]->name==name)
                    {
                        flag=1;
                        now->wjj[j]->flag=0;
                        now->wjj[j]->name="";
                        break;
                    }
                }
                if(!flag)
                    puts("No such directory!");
            }
        }
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    /*
    20
    mkdir 123
    cd 123
    rm 123
    cd ..
    rm 123
    rmdir 12
    rmdir 123
    cd 123
    ls
    */
    
    /*
    20
    cd ..
    mkdir 123
    mkdir 456
    mk 123
    mk 456
    ls
    touch 123
    touch 456
    ls
    rmdir 456
    mkdir 456
    ls
    cd 123
    ls
    touch mhe
    touch why
    cd ..
    ls
    */
    View Code

      做题顺序:

        T1好难啊,不会。

        T2好难啊,不会。

        T3..模拟?。。好像很有意思,做一下。

        T3 2.5h做完,给写的太麻烦了,可以很简洁的写完的。然后T2拿第一个点,然后剩下一小时搞T1,最后10min赵老师来让着交题,但我还没写完。然后继续强搞,在最后10min成功拿下T1的40分暴力分。  但是T2理解错题意,那10分并没有拿到。

       得分:

          T1 40

          T2 0

          T3 100

          Sum 140

      。。。。感觉这几天考的三场试都rp大爆发啊。但是今天的题目貌似并不难,可就是不会做。大概我深受一看不会就打暴力思想的影响吧,毕竟以前吃了考试老想正解不打暴力的很大的亏。但是一看不会就打暴力确实太暴力了。T2应该可以想出来的,但是T3模拟太耗了。         为什么总是不能比较让自己满意地做一套题呢。

  • 相关阅读:
    linux基础学习-6.4-Linux无法上网排查流程
    [JSOI2007][BZOJ1029] 建筑抢修
    [HNOI2003][BZOJ1216] 操作系统
    [Apio2009][BZOJ1179] Atm
    [Tjoi2013][BZOJ3172] 单词
    AC自动机学习笔记
    [转]一个比较通俗的KMP算法讲解
    [HAOI2008][BZOJ1042] 硬币购物
    [NOI2007][BZOJ1491] 社交网络
    [SCOI2009][BZOJ1295] 最长距离
  • 原文地址:https://www.cnblogs.com/lovewhy/p/8687840.html
Copyright © 2011-2022 走看看