• SICNU 2018 Summer Training #7


      打起来很累,感觉不是很好,但是题意都不是特别难懂

      Maratona de Programa¸c˜ao da SBC 2013

      首先是A题Zero or One,签到题

      给三个数(0或1),找不一样的是哪个,如果都一样就输出*

      

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int main()
    {
        int a,b,c;
        cin>>a>>b>>c;
        if(a==b&&b==c) cout<<'*'<<endl;
        else if(a==b) cout<<'C'<<endl;
        else if(a==c) cout<<'B'<<endl;
        else if(b==c) cout<<'A'<<endl;
        return 0;
    }

     D题Folding Machine感觉肯定很难,但是就是用莫名其妙,xjbg的方法水过去了

    题意:给一串序列,问是否能够通过折叠转变成另一个序列

    我的思路就是第二个序列的数可以用第一个序列的数表示就OK了,但是我只判断了第二个序列中的第一个数,就ac了。。

    #include <cstdio>
    #include <iostream>
    #include <map>
    #include <algorithm>
    using namespace std;
        int cmp(int x,int y){
        return x>y;
        }
    int main()
    {
        int n,m;
        int sum1=0,sum2=0;
        int a[20],b[20];
        map<int,int>s;
        cin>>n;
        for(int i=0;i<n;i++){
            cin>>a[i];
            s[a[i]]++;
            sum1+=a[i];
        }
        sort(a,a+n,cmp);
        cin>>m;
        for(int i=0;i<m;i++){
            cin>>b[i];
            sum2+=b[i];
        }
        if(sum1==sum2){
            for(int i=0;i<n;i++){
                if(b[0]>=a[i]){
                    if(s[a[i]]!=0){
                        b[0]-=a[i];
                        s[b[0]-a[i]];
                    }
                }
            }
            if(b[0]==0) cout<<'S'<<endl;
            else cout<<'N'<<endl;
        }
        else cout<<'N'<<endl;
    }

    E题Dangerous Dive,也是道签到题,直接上代码吧

    #include <cstdio>
    #include <iostream>
    #include <queue>
    using namespace std;
    int main()
    {
        int n,m,t;
        int a[10005]={0};
        cin>>n>>m;
        for(int i=0;i<m;i++){
            cin>>t;
            a[t]=1;
        }
        if(n==m){
            cout<<'*'<<endl;
            return 0;
        }
        for(int i=1;i<=n;i++){
            if(a[i]==0) cout<<i<<' ';
        }
        return 0;
    }

    F题Triangles,是过的人超级多的,以为是道签到题,没想到没想到啊,wa了好多次还没写出来了,还有tle,后来经过大佬的提示可以通过前缀和降低复杂度。

    题意是给圆上一些点,告诉每个点之间的弧长,,然后问可以构造多少个不同的等边三角形

     一开始想的比较简单,就是用一个两倍数组存,然后枚举起点,看能不能从这个点开始构造一个等边三角形,也就是能不能求和到总弧长的三分之一,然后发现tle了,后来发不需要枚举这么多点,因为像之前这么枚举的话,要重复算三倍的点,只需要枚举第一个等边三角形的两个点之间的点就OK了,发现又tle在之后的样例了,这个就很麻烦,最后在大佬的提示下,用前缀和降低复杂度,然后用map去存前缀和。。

    #include <iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<queue>
    #include<map>
    using namespace std;
    map<int,int>vis;
    int main()
    {
    int n,m,a[100001]={0},j,temp=0,i,k,pre[100001]={0};
    cin>>n;
    int sum=0;
    for(i=1;i<=n;i++)
    {
        cin>>a[i];
        pre[i]=a[i]+pre[i-1];
        vis[pre[i]]++;
        sum+=a[i];
    }
    if(sum%3!=0)
        cout<<0<<endl;
    else
    {
        int ans=sum/3;
        int count=0,temp=0,cnt=0;
     for(i=1;i<=n;i++)
     {
             if(vis[ans+pre[i]]&&vis[ans*2+pre[i]]) cnt++;
    }
     cout<<cnt<<endl;
    }
    
    return 0;
    }

    G题Lines of Containers,也是比较简单的吧

    给一个n*m的矩阵,里面有1—n*m的数,问能否通过互换行或者列的方式让这个矩阵变成很舒服的矩阵,就是a【i】【j】=(i-1)*m+j

    思路:就是把矩阵中1给找出来,记一下1的行和列,然后对1这一行(一列)进行排序,但是需要进行一些改变,就是在换序的时候是对这一列(行)进行换序,最后就只需要判断排序之后的这个矩阵能不能变成题目要求的这样。

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int main()
    {
        int num[305][305];
        int n,m;
        int a=0,b=0;
        int sum=0;
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                cin>>num[i][j];
                if(num[i][j]==1){
                    a=i;
                    b=j;
                }
            }
        }
        for(int i=1;i<=m;i++){
            if(num[a][i]!=i){
                int flag=0;
                for(int j=i+1;j<=m;j++){
                    if(num[a][j]==i){
                        if(i==1) b=j;
                        sum++;
                        flag=1;
                        for(int t=1;t<=n;t++){
                              swap(num[t][j],num[t][i]);
                        }
                    }
                }
                if(flag==0){
                    cout<<'*'<<endl;
                    return 0;
                }
            }
        }
        for(int i=1;i<=n;i++){
            if(num[i][b]!=(i-1)*m+b){
                int flag=0;
                for(int j=i+1;j<=n;j++){
                    if(num[j][b]==(i-1)*m+b){
                        sum++;
                        flag=1;
                        for(int t=1;t<=m;t++){
                              swap(num[j][t],num[i][t]);
                        }
                    }
                }
                 if(flag==0){
                    cout<<'*'<<endl;
                    return 0;
                }
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(num[i][j]!=((i-1)*m+j)){
                    cout<<'*'<<endl;
                    return 0;
                }
            }
        }
        cout<<sum<<endl;
        return 0;
    }

    还有就是C题,题很长,题意也比较难懂,所以在比赛中就没有去碰。

    后面队友在补题的时候,说可以用dfs和拓扑排序去做。想了想贼有道理

    题意就是,先给一些上下级的关系,然后构成一张关系图,然后会给你一些修改和查询,如果是修改的话就是交换两个人的位置,如果是查询的话,就是查询要查询的人的上级(包括直接和间接)中年龄最小的,如果比自己小,就输出这个年龄,如果没有即输出*

    思路就是DFS,但是在修改的时候用数组进行维护,就是基本的关系网不变,但是在每次修改的时候,将位置修改的放入数组中,如果查询到这个人的时候判断一下,如果修改过,就到修改的这个人的位置上再进行dfs

  • 相关阅读:
    MVC中CheckBox
    Python中的高级数据结构
    高级正则表达式技术(Python版)
    程序员可以兼任项目经理吗?
    浅谈五大Python Web框架
    学习Python编程的11个资源
    Python 代码性能优化技巧
    python多线程ctrl-c退出问题
    Python 笔记 : 类和继承
    Python的OO思想
  • 原文地址:https://www.cnblogs.com/maybe96/p/9438789.html
Copyright © 2020-2023  润新知