zoukankan      html  css  js  c++  java
  • SICNU 2018 Summer Training #2

       这场比赛感觉起来还是比较基础的吧,一半多的题目应该都是可以做的,但是还是太菜了,只做了5题。。也是因为时间比较赶有几题过题少的都没看题

    b题在比赛的时候没做出来,wa了几次就转其他题目了,思路应该比较常规,就是纸上模拟找下规律,因为数据比较大所以也不能直接模拟,规律应该就是如果第一行可以放满,就每个人都有一个,然后分奇偶

    如果是偶数行数就前面n-1个可以得到糖果,否则就是后面n-1个可以得到糖果,然后其实就是中间的不影响,只是第一个和最后一个是减半的,而且根据奇偶要-1或者不变,然后就模拟最后一行就好了,然后特判一下没排满第一行的情况就行了。

    c题题意一开始没读懂,以为是n&(n-1)的情况,然后wa了,后面Google翻译了一下就是二进制翻转,找小于他本身的最大的那个数,其实就是找1了,如果找到了第一个1,就翻转就行了,最后输出1的位数

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <set>
    #include <map>
    #include <string>
    using namespace std;
    
    int main()
    {
        int t;
        int n,m;
        int s[10000];
        cin>>t;
        while(t--){
            cin>>n;
            int a=0;
            m=0;
            while(n>0){
                s[a++]=n%2;
                n/=2;
            }
            for(int i=0;i<a;i++){
                m++;
                if(s[i]==1) break;
            }
            cout<<m<<endl;
        }
        return 0;
    }

    然后是D题,实质上就是找规律,如果n==m 就很好办,正方形经过所以块的边就是n*(n+1)/2,否则就必须分n和m的奇偶情况

    如果奇偶性相同就是跟相同的情况相似,只不过有两种情况就是取两种情况的最小m*(n+1)/2

    如果奇偶性不同,就需要对折,然后与直接的m*(n+1)/2,进行比较

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <set>
    #include <map>
    #include <cstring>
    using namespace std;
        int cmp(int x,int y){
            return x>y;
        }
    int main() {
        int t;
        long long n,m;
        cin>>t;
        while(t--){
            cin>>n>>m;
            if(n==m){
                cout<<n*(n+1)/2<<endl;
            }
            else{
                long long s;
                if(n%2==0&&m%2==0) s=min(n*(m+1)/2,m*(n+1)/2);
                else if(n%2==1&&m%2==0) s=min(m*(n/2+1)/2+(m/2+1)*(n/2),m*(n+1)/2);
                else if(n%2==0&&m%2==1) s=min((m/2+1)*n/2+(m/2)*(n/2+1),n*(m+1)/2);
                else s=min((n+1)*m/2,(m+1)*n/2);
                cout<<s<<endl;
            }
        }
        return 0;
    }

    f题思路挺好想的,就是贪心,先用map存,排序从大到小进行判断,每个数从1到平方根判断是否能被整除,如果能,再判断两个因数是否在map里,如果小因数在,就直接break,如果大因数在就需要继续判断是否还有比这个因数小的存在,思路和实现没太大的问题,主要是这题有点卡时间,一开始一直tle,不断修改,也不知道哪里有问题,后来发现使用cin和cout进行输入和输出是不行的,要使用printf或者scanf,或者取消流同步,然后就是在两个因数的判断上可能存在一些易错点

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <set>
    #include <map>
    #include <cstring>
    using namespace std;
        int cmp(int x,int y){
            return x>y;
        }
    int main()
    {
        int t;
        scanf("%d",&t);
        int n,m;
        int num[100005];
        map<int,int>s;
        while(t--){
            long long sum=0;
            s.clear();
            scanf("%d",&n);
            for(int i=0;i<n;i++) {
                scanf("%d",&num[i]);
                s[num[i]]=1;
            }
            sort(num,num+n,cmp);
            for(int i=0;i<n;i++){
                int t=0;
                int ss=0;
                for(int j=1;j<=sqrt(num[i]);j++){
                    if(num[i]%j==0){
                        if(s[j]!=0){
                            num[i]=j;
                            t=0;
                            break;
                        }
                        else if(s[num[i]/j]){
                            ss=num[i]/j;
                            t=1;
                        }
                    }
                }
                if(t==1) num[i]=ss;
                sum+=num[i];
            }
            printf("%lld
    ",sum);
        }
        return 0;
    }

    h题应该是个签到题,挺简单的,O(N)复杂度找前后两数和的最大值

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <set>
    #include <map>
    #include <string>
    using namespace std;
    
    int main()
    {
        int n,m;
        int num[2005];
        int t;
        cin>>t;
        while(t--){
            cin>>n;
            int maxn=-1;
            for(int i=0;i<2*n;i++) cin>>num[i];
            for(int i=0;i<n;i++){
                maxn=max(maxn,num[i]+num[2*n-i-1]);
            }
            cout<<maxn<<endl;
        }
        return 0;
    }

    i题应该也是签到题

    大意就是给一个数,然后告诉需要划分几份,找最平均的划分(最大值与最小值的差最小)

    其实就是两种情况,一直是只有n/m的情况,一种就是有n/m和n/m+1的情况

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <set>
    #include <map>
    #include <string>
    using namespace std;
    
    int main()
    {
        int n,m;
        int t;
        cin>>t;
        while(t--){
            cin>>n>>m;
            if(m>n){
                cout<<-1<<endl;
                continue;
            }
            if(m==n){
                for(int i=0;i<n;i++){
                    if(i!=0) cout<<' ';
                    cout<<1;
                }
            }
            else{
                if(n%m==0){
                    for(int i=0;i<m;i++){
                    if(i!=0) cout<<' ';
                    cout<<n/m;
                }
                }
                else {
                    int t=n/m;
                    int s=n-t*m;
                    for(int i=0;i<m-s;i++){
                        if(i!=0) cout<<' ';
                        cout<<t;
                    }
                    for(int i=0;i<s;i++) cout<<' '<<t+1;
                }
            }
            cout<<endl;
            }
        return 0;
    }

     

  • 相关阅读:
    一对一关联映射
    hibernate 中的 lazy=”proxy” 和 lazy=”no-proxy” 的区别
    Hibernate 延迟加载和立即加载
    hibernate inverse属性的作用
    Hibernate一对多关联
    Hibernate双向多对多关联
    SQL编程
    XML(DOM解析)
    UDP模式聊天
    Thread对象的yield(),wait(),notify(),notifyall()
  • 原文地址:https://www.cnblogs.com/maybe96/p/9370791.html
Copyright © 2011-2022 走看看