• 中南大学2019年ACM寒假集训前期训练题集(入门题)


    A: 漫无止境的八月

    Description

    又双叒叕开始漫无止境的八月了,阿虚突然问起长门在这些循环中团长哪几次扎起了马尾,他有多少次抓住了蝉等等问题,长门一共回复n个自然数,每个数均不超过1500000000(1.5*10^9)。已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。

    Input

    第1行是整数n,表示回复的自然数的个数。n<=1e6
    第2~n+1行每行一个自然数。

    Output

    包含m行(m为n个自然数中不相同数的个数),按照自然数从小到大的顺序输出。每行输出两个整数,分别是自然数和该数出现的次数,其间用一个空格隔开。

    Sample Input

    8
    2
    4
    2
    4
    5
    100
    2
    100
    

    Sample Output

    2 3
    4 2
    5 1
    100 2

    题意:给你n个数,你要找到输入的每个数出现了多少次,并从小到大的输出该个数对应的值和出现的次数。
    解法:这题我们可以利用map来存储,我们知道map的key,value在输入进去在之后map会自动的以key值进行排序,所以我们利用这个性质,key存放对应的数值,value存放对应的次数,然后输出map就可以了。
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <map>
    using namespace std;
    int n;
    map<int,int>m;
    
    int main()
    {
        scanf("%d",&n);
        m.clear();
        int x;
        while(n--)
        {
            scanf("%d",&x);
            if(m.count(x)==0)
                m[x]=1;
            else
                m[x]++;
        }
        map<int,int>::iterator iter;
        for(iter=m.begin();iter!=m.end();iter++)
            printf("%d %d
    ",iter->first,iter->second);
        return 0;
    }
    
    /**********************************************************************
        Problem: 2204
        User: jk1601zr
        Language: C++
        Result: AC
        Time:148 ms
        Memory:2424 kb
    **********************************************************************/

    B: Magia

    Description

    吼姆啦酱来救被变成魔女的纱耶香攻击的小圆辣!魔境背景中的指挥家指挥着这场表演的音乐,吼姆啦酱发现一个规律,如果过一串音符是回文的,那么这串音符会实物化来攻击她,现在给出一段音符,判断它是否是回文的。一个左右对称的自然数称为回文数,即这个数从左往右读与从右往左读是一样的,如121,686,13731,8668等都是回文数。

    Input

    输入一个int范围内的自然数N,判断它是否是回文数。如果是就输出这个回文数,若不是则输出-1。

    Output

    只有一行,N是回文数,就输出N,不是就输出-1。

    Sample Input

    686

    Sample Output

    686

    题意:判断回文。
    解法:直接存在字符串数组里面,感觉会方便比较吧,看个人习惯。然后区分奇数偶数对应的判断就行了。
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <map>
    using namespace std;
    const int maxn=1000;
    char s[maxn];
    
    int main()
    {
        scanf("%s",s);
        int len=strlen(s);
        bool flag=false;
        if(len%2==1)
        {
            int temp=len/2;
            for(int i=0;i<temp;i++)
            {
                if(s[i]!=s[len-i-1])
                {
                    flag=true;
                    break;
                }
            }
            if(flag)
                printf("-1
    ");
            else
            {
                for(int i=0;i<len;i++)
                    printf("%c",s[i]);
                printf("
    ");
            }
        }
        else
        {
            int temp=len/2;
            for(int i=0;i<=temp;i++)
            {
                if(s[i]!=s[len-i-1])
                {
                    flag=true;
                    break;
                }
            }
            if(flag)
                printf("-1
    ");
            else
            {
                for(int i=0;i<len;i++)
                    printf("%c",s[i]);
                printf("
    ");
            }
        }
        return 0;
    }
    
    
    /**********************************************************************
        Problem: 2205
        User: jk1601zr
        Language: C++
        Result: AC
        Time:4 ms
        Memory:2024 kb
    **********************************************************************/

    C: 长门的运动会

    Description

    运动会,好开心~

    CSU (California State University) 正在举行一场特殊的接力跑比赛,比赛在环形跑道上进行,同一支队伍的所有人从同一个位置向相同的方向出发,当需要接力的两个人再次相遇时,他们就要交接棒。最后总成绩是以队伍跑的总路程计算的。

    接力比赛

    现在接力的第一棒在Nagato手中,需要把它交给Kyon。在长度为C的环形跑道上,他们出发了!Nagato以速度A匀速跑动,Kyon以速度B匀速跑动。他们在经过多长时间后可以再次相遇?

    Input

    多组数据,第一行为一个整数T (1 ≤ T ≤ 106),表示数据组数。

    之后每行是一组数据,有三个整数C, A, B (1 ≤ C, A, B ≤ 109, A ≠ B),分别表示环形跑道的长度,Nagato的速度和Kyon的速度。

    Output

    每行输出一个数,表示再次相遇所需的时间。绝对误差或相对误差小于10−5则认为是正确的。

    Sample Input

    2
    3 1 2
    5 10 7

    Sample Output

    3.00000000
    1.66666667

    题意:两个人从同一起点一起跑,看谁先比另一个人多跑一圈。
    解法:求出两个人速度的差值,然后简单的物理计算。
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <map>
    using namespace std;
    const int maxn=1000;
    int T;
    int c,a,b;
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d %d %d",&c,&a,&b);
            int temp=abs(a-b);
            double ans=c*1.0/(temp);
            printf("%.8f
    ",ans);
        }
        return 0;
    }
    
    
    
    /**********************************************************************
        Problem: 2158
        User: jk1601zr
        Language: C++
        Result: AC
        Time:316 ms
        Memory:2024 kb
    **********************************************************************/

    D: 剪刀石头布

    Description

     

    现在一共有N个人(分别记为1, 2, …, N)在玩剪刀石头布,如果知道他们每个人都出了什么,你能找出来谁是winner吗?

    当且仅当一个人可以赢其他所有人时,才称这个人是winner。

    我们将剪刀记作2,石头记作0,布记作5,那么胜负关系就应当是2能赢5,5能赢0,0能赢2。

     

    Input

     

    输入数据的第一行包含一个整数T ( 1 <= T <= 150),表示接下来一共有T组测试数据。

    每组测试数据的第一行包含一个整数N (2 <= N <= 100000)表示一共有N个人在玩剪刀石头布,接下来一行一共有N个数,每个数均为0、2或5中的某一个,依次描述了这N个人分别出了什么,其中第i个整数描述了第i个人出了什么。

     

    Output

     

    对于每组数据,用一行输出一个整数表示winner是第几个人([1, N]中的某个整数)。

    如果不存在winner,则用一行输出“No winner”(不包括引号)。

     

    Sample Input

    3
    3
    5 5 2
    3
    2 0 0
    3
    0 2 5
    

    Sample Output

    3
    No winner
    No winner

    题意:模拟剪刀石头布的游戏,我们知道三个模式当且仅当出现两种,并且一个能打败另一个的时候才会有winner。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <map>
    #include <set>
    using namespace std;
    const int maxn=100005;
    int T;
    int n,x;
    //struct Node
    //{
    //    int val;
    //    int cnt;
    //};
    int a[3],pos[3];
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
           scanf("%d",&n);
           for(int i=0;i<3;i++)
               a[i]=pos[i]=0;
           for(int i=0;i<n;i++)
           {
               scanf("%d",&x);
               if(x==2)
               {
                   a[0]++;pos[0]=i+1;
               }
               else if(x==0)
               {
                   a[1]++;pos[1]=i+1;
               }
               else if(x==5)
               {
                   a[2]++;pos[2]=i+1;
               }
           }
    //       if(a[0]!=0&&a[1]!=0&&a[2]!=0)
    //            printf("No winner
    ");
            if(a[0]==1&&a[1]==0)
                printf("%d
    ",pos[0]);
            else if(a[1]==1&&a[2]==0)
                printf("%d
    ",pos[1]);
            else if(a[2]==1&&a[0]==0)
                printf("%d
    ",pos[2]);
            else
                printf("No winner
    ");
        }
        return 0;
    }
    
    
    
    
    
    /**********************************************************************
        Problem: 1202
        User: jk1601zr
        Language: C++
        Result: AC
        Time:0 ms
        Memory:0 kb
    **********************************************************************/

    E: 全场最水题之陈兴老师与比赛

    Description

    大家都知道ACM比赛罚时很重要。比如说你做A题要10分钟,B题要15分钟,如果先做A题再做B题,那么在ranking上的时间就是10 + (10)+ 15 = 35。如果先做B题再做A题总罚时就是15+(15)+

    10=40.现在陈兴老师要做一场比赛,比赛有n道题, 总时间是300分钟。我们的陈兴老师仅仅看题目就可以知道他做每道题需要的时间。比如一般的比赛,陈兴老师做第一题需要1分钟,第二题2分钟,依此类推,陈兴老师只需要66分钟就可以AK一场11道题的比赛。PS: 陈兴老师做题都是1Y,膜拜陈兴老师Orz!

     

    Input

    第一行是一个数字n  0<n<=25

    第二行是n个数字,第i个数字代表陈兴老师出编号为i的题所需要的时间 ti( 0 < ti <= 80)。

     

    Output

    第一行输出陈兴老师的出题数和Penalty(总时间)

    以下按照顺序输出陈兴老师出题的顺序,每行一个编号。(详见输出样例)PS:时间一样的按编号升序输出。

     

    Sample Input

    3
    1 2 3
    4
    1 2 3 4
    6
    60 60 60 60 60 60
    

    Sample Output

    3 10
    1
    2
    3
    4 20
    1
    2
    3
    4
    5 900
    1
    2
    3
    4
    5
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <map>
    using namespace std;
    struct Node
    {
        int t;
        int num;
    }node[30];
    int cmp(Node a,Node b)
    {
        if(a.t!=b.t)
            return a.t<b.t;
        else
            return a.num<b.num;
    }
    int main()
    {
        int n,i,j,sum,k;
        while(cin>>n)
        {
            for(i=0;i<n;i++)
            {
                cin>>node[i].t;
                node[i].num=i+1;
            }
            sort(node,node+n,cmp);
            sum=0;k=0;
            for(i=0;i<n;i++)
            {
                if(k+node[i].t>300)
                    break;
                k+=node[i].t;
            }
            int temp1=i,temp2=i;
            for(i=0;i<temp1;i++)
            {
                sum+=node[i].t*(temp2--);
            }
            cout<<temp1<<" "<<sum<<endl;
            for(i=0;i<temp1;i++)
            {
                cout<<node[i].num<<endl;
            }
        }
        return 0;
    }
    
    
    /**********************************************************************
        Problem: 1315
        User: jk1601zr
        Language: C++
        Result: AC
        Time:320 ms
        Memory:2024 kb
    **********************************************************************/

    F: 字符画

    Description

    读入 w,请输出 2018 的字符画,两个数字之间有 w 个空格。具体格式请参考样例输出。

    • 1 ≤ w ≤ 2018

    Input

    输入文件只包含 1 个整数 w.

    Output

    输出 5 行,每行 12 + 3w 个字符(只包含 o 和 . 两种,字符画的部分用 o,空格的部分用 .),以换行符结尾。

    Sample Input

    2

    Sample Output

    ooo..ooo..ooo..ooo
    ..o..o.o...o...o.o
    ooo..o.o...o...ooo
    o....o.o...o...o.o
    ooo..ooo..ooo..ooo

    直接模拟就行。
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <map>
    using namespace std;
    int n;
    int main()
    {
        scanf("%d",&n);
        printf("ooo");
        for(int i=0;i<n;i++)
            printf(".");
        printf("ooo");
        for(int i=0;i<n;i++)
            printf(".");
        printf("ooo");
        for(int i=0;i<n;i++)
            printf(".");
        printf("ooo");
        printf("
    ");
    
        printf("..o");
        for(int i=0;i<n;i++)
            printf(".");
        printf("o.o");
        for(int i=0;i<n;i++)
            printf(".");
        printf(".o.");
        for(int i=0;i<n;i++)
            printf(".");
        printf("o.o");
        printf("
    ");
    
        printf("ooo");
        for(int i=0;i<n;i++)
            printf(".");
        printf("o.o");
        for(int i=0;i<n;i++)
            printf(".");
        printf(".o.");
        for(int i=0;i<n;i++)
            printf(".");
        printf("ooo");
        printf("
    ");
    
        printf("o..");
        for(int i=0;i<n;i++)
            printf(".");
        printf("o.o");
        for(int i=0;i<n;i++)
            printf(".");
        printf(".o.");
        for(int i=0;i<n;i++)
            printf(".");
        printf("o.o");
        printf("
    ");
    
        printf("ooo");
        for(int i=0;i<n;i++)
            printf(".");
        printf("ooo");
        for(int i=0;i<n;i++)
            printf(".");
        printf("ooo");
        for(int i=0;i<n;i++)
            printf(".");
        printf("ooo");
        printf("
    ");
        return 0;
    }
    
    
    /**********************************************************************
        Problem: 2163
        User: jk1601zr
        Language: C++
        Result: AC
        Time:8 ms
        Memory:2024 kb
    **********************************************************************/

    H: joghs

    Description

    编号为1、 2、 3、 …、 n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。从指定编号为1的人开始,按顺时针方向自1开始报数,报到指定值m时停止报数,报第m的人出列,并将他的密码作为新的m值,从他在顺时针方向的下一个人开始,重新从1开始报数,如此类推,直至所有的人全部出列为止。输入n(n<=1000),m(m<=30000)及密码值(<=10000),试设计一个程序求出列顺序。

    Input

    有二行,第一行,N和M,第二行,N个小于等于10000的密码值,中间用空格隔开。

    Output

    只有一行,就是出列的顺序,编号间以空格隔开。

    Sample Input

    6 7
    1 4 2 8 5 7

    Sample Output

    1 2 6 3 5 4

    题意:约瑟夫环问题,但是要注意m值是在变化的,开始看题没注意。
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <map>
    #include <vector>
    #include <list>
    using namespace std;
    const int maxn=1005;
    int n,m;
    int a[maxn];
    int main()
    {
        scanf("%d %d",&n,&m);
        list<int>l;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            l.push_back(i);
        }
        list<int>::iterator it;
        int cnt=1;
        for(it=l.begin();l.size()!=1;)
        {
            if(cnt++==m)
            {
                printf("%d ",*it);
                m=a[*it];
                it=l.erase(it);
                cnt=1;
            }
            else
                it++;
            if(it==l.end())
                it=l.begin();
        }
        printf("%d
    ",*l.begin());
        return 0;
    }
    
    
    /**********************************************************************
        Problem: 2053
        User: jk1601zr
        Language: C++
        Result: AC
        Time:24 ms
        Memory:2028 kb
    **********************************************************************/

    G: N个数字求和

    这题数据有锅,待补。

    I: 英文单词

    Description

    编写程序,读入一行文本,文本是一个长度不超过255的英文句子,单词之间有一个或一个以上的空格,输出:
    ①统计单词的个数;
    ②一个对应的英文句子,其中原句中的所有小写字母均转换成大写字母,大写字母转换成小写字母;
    ③删除所有空格符后对应的句子。

    Input

    只有一行,就是一个英文句子

    Output

    有三行,第一行单词的个数,第二行,转换了大小写的英文句子,第三行删除空格的句子。

    Sample Input

    Who are you?

    Sample Output

    3
    wHO ARE YOU?
    Whoareyou?

    题意:直接模拟就行,但是要注意这个字符串的读入,要用到getline,不然空格读入不了。
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <map>
    using namespace std;
    const int maxn=300;
    char s[maxn];
    int main()
    {
        cin.getline(s,256);
        int len=strlen(s);
    //    cout<<len<<endl;
        int cnt=0;
        for(int i=0;i<len;i++)
        {
            if(s[i]==' '&&((s[i+1]>='a'&&s[i+1]<='z')||(s[i+1]>='A'&&s[i+1]<='Z')))
                cnt++;
        }
        if(s[0]!=' ')
            cnt++;
        printf("%d
    ",cnt);
        for(int i=0;i<len;i++)
        {
            if(s[i]>='a'&&s[i]<='z')
                printf("%c",s[i]-32);
            else if(s[i]>='A'&&s[i]<='Z')
                printf("%c",s[i]+32);
            else
                printf("%c",s[i]);
        }
        printf("
    ");
        for(int i=0;i<len;i++)
        {
            if(s[i]==' ')
                continue;
            else
                printf("%c",s[i]);
        }
        printf("
    ");
        return 0;
    }
    
    
    
    /**********************************************************************
        Problem: 2050
        User: jk1601zr
        Language: C++
        Result: AC
        Time:4 ms
        Memory:2024 kb
    **********************************************************************/

    J: Num

    Description

    编一程序,输入正整数N(N在2~32767之间), 求它的最大质因子(包括它本身)。

    Input

    只有一行,就是正整数N

    Output

    所求的最大质因子

    Sample Input

    7

    Sample Output

    7
    题意:题面就很清楚了。
    解法:预处理出2~32767所有的质数,然后从大到小对应的判断就行了。
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <map>
    #include <set>
    using namespace std;
    const int maxn=323767;
    set<int>s;
    int check[maxn];
    int n;
    void init()
    {
        memset(check,0,sizeof(check));
        for(int i=2;i<=maxn;i++)
        {
            if(!check[i])
                s.insert(i);
            for(int j=i+i;j<=maxn;j+=i)
                check[j]=1;
        }
    }
    int main()
    {
        init();
        scanf("%d",&n);
        for(int i=n;;i--)
        {
            if(s.count(i)&&n%i==0)
            {
                printf("%d
    ",i);
                break;
            }
        }
        return 0;
    }
    
    
    
    
    /**********************************************************************
        Problem: 2051
        User: jk1601zr
        Language: C++
        Result: AC
        Time:32 ms
        Memory:4608 kb
    **********************************************************************/

    K: 时间旅行

    Description

    假设 Bobo 位于时间轴(数轴)上 t0 点,他要使用时间机器回到区间 (0, h] 中。

    当 Bobo 位于时间轴上 t 点,同时时间机器有 c 单位燃料时,他可以选择一个满足 xhhc⌈xh⌉⋅h≤c 的非负整数 x, 那么时间机器会在 [0, x]中随机整数 y,使 Bobo 回到 (t − y) 点,同时消耗 y 单位燃料。 (其中 ⌈ ⋅ ⌉ 表示上取整)

    因为时间机器的随机性,对于给出的参数 h 和时间机器剩余燃料 c,Bobo 想知道能够保证回到区间 (0, h] 中的 t0 的最大值。

    • 1 ≤ h ≤ 109
    • 0 ≤ c ≤ 109
    • 数据组数不超过 105.

    Input

    输入文件包含多组数据,请处理到文件结束。

    每组数据包含 2 个整数 h 和 c.

    Output

    对于每组数据输出 1 个整数表示 t0 的最大值。

    Sample Input

    100 99
    100 100
    100 149
    

    Sample Output

    100
    101
    150

    模拟,读清题意就可以了。
    #include <iostream>
    #include <stdio.h>
    #include <string>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    #include <queue>
    #include <set>
    #include <stack>
    #include <vector>
    #include <deque>
    #include <list>
    using namespace std;
    typedef long long LL;
    const int INF=0x3f3f3f3f;
    const double eps=1e-8;
    const double pi=acos(-1.0);
    const int MOD=10056;
    const int maxn=2016;
    int h,c;
    
    int main()
    {
        while(scanf("%d %d",&h,&c)!=EOF)
        {
            if(h>c)
                printf("%d
    ",h);
            else
                printf("%d
    ",c+1);
        }
        return 0;
    }
    /**********************************************************************
        Problem: 2165
        User: jk1601zr
        Language: C++
        Result: AC
        Time:112 ms
        Memory:2024 kb
    **********************************************************************/
  • 相关阅读:
    Win10 VMware虚拟机无法打开内核设备“\.Globalvmx86“
    搜索算法总结
    经典排序算法
    Markdown Test
    PAT L2-020 功夫传人【BFS】
    PAT l2-018 多项式A除以多项式B 【多项式+模拟】
    PAT l2-010 排座位 【并查集】
    二叉树的前中后序遍历关系 【非原创】
    PAT L2-005. 集合相似度 【stl set】
    PAT L2-004. 这是二叉搜索树吗?【前序遍历转化为后序遍历】
  • 原文地址:https://www.cnblogs.com/jkzr/p/10096180.html
Copyright © 2020-2023  润新知