• 浙江省10th程序设计竞赛部分题解


    A题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3705

    第一行给出一个数字,代表样例的个数

    第二行给出两个数n和m,代表人数和需要选出的排名的前m个人

    第三四行分别给出MaoMao Selection和Surgeon Contest的题目数量与题号

    第五行给出拿到前三等奖的数目,接下来给出每个获奖的队伍和获得的排名

    最后给出每个人的信息,包括人名,队名,性别,OJ里的做题数,参加比赛的数目

    然后给出题号与比赛的得分

    而每个人的得分计算是这样:

    首先是做的题所得的分:1.在MaoMao Selection做的题得2.5分

                                   2.在Surgeon Contest做的题得1.5分

                                    3.如果不在这两个地方做的题并且题号为素数,得1分

                                    4.否则0.3分

    如果所在的队伍得奖了:一等奖36分,二等27,三等18

    如果是女的:加33分

    如果参加过比赛,则取第三高的分数,计算公式Pts = max(0, (r - 1200) / 100) * 1.5为得分,如果小于3次比赛则不算

    题意理清楚了之后,按照题目的叙述模拟即可。

    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <algorithm>
    #include <iomanip>
    #include <map>
    #include <cmath>
    using namespace std;
    #define INF 1e-3
    int t;
    int n,m,r,s,q,pri,p,c,index;
    int inS[505],old[505],rating[1005];
    char sex;
    map<string,int> team;
    struct node
    {
        string name;
        double rat;
    };
    node str[505];
    string S,temp;
    bool prime(int x)
    {
        if(x<=1)
        return false;
        if(x==2)
        return true;
        if(x%2==0)
        return false;
        for(int i=3;i<=x/2;i+=2)
        {
            if(x%i==0)
            return false;
        }
        return true;
    }
    bool cmp(node a,node b)
    {
        if(fabs(a.rat-b.rat)<INF)
        return a.name<b.name;
        return a.rat>b.rat;
    }
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            team.clear();
            scanf("%d%d",&n,&m);
            scanf("%d",&r);
            for(int i=0;i<r;++i)
            scanf("%d",inS+i);
            sort(inS,inS+r);
            scanf("%d",&s);
            for(int i=0;i<s;++i)
            scanf("%d",old+i);
            sort(old,old+s);
            scanf("%d",&q);
            for(int i=1;i<=q;++i)
            {
                cin>>S>>pri;
                if(pri>=1&&pri<=3)
                team[S]=pri; 
            }
            for(int i=0;i<n;++i)
            {
                cin>>S>>temp>>sex;
                str[i].name=S;
                str[i].rat=0.0;
                if(team[temp])
                {
                    str[i].rat+=(5-team[temp])*9.0;
                }
                if(sex=='F')
                str[i].rat+=33.0;
                cin>>p>>c;
                for(int j=0;j<p;++j)
                {
                    scanf("%d",&index);
                    if(binary_search(inS,inS+r,index))
                        str[i].rat+=2.5;
                    else if(binary_search(old,old+s,index))
                    str[i].rat+=1.5;
                    else if(prime(index))
                    str[i].rat+=1.0;
                    else 
                    str[i].rat+=0.3;
                }
                for(int j=0;j<c;++j)
                {
                    scanf("%d",rating+j);
                }
                if(c>=3)
                {
                    sort(rating,rating+c);
                    str[i].rat+=max(0.0,(rating[c-3]-1200.0)*1.0/100)*1.5;
                }
        
            }
            sort(str,str+n,cmp);
            for(int j=0;j<m;++j)
            {
                cout<<str[j].name<<' '<<setiosflags(ios::fixed)<<setprecision(3)<<str[j].rat<<endl;
            }
        }
        return 0;
    }

    B题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3706

    题意:给你两个砝码。你可以把其中一个砝码拆分成两个。问你用拆分后的砝码最多可以组合出多少重量。

    水题,暴力枚举组合,用set排序去重,注意最后处理为0的情况。

    #include <iostream>
    #include <cstdio>
    #include <set>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    int cal(int a,int b,int c)
    {
        set <int> cnt;
        cnt.insert(abs(a));
        cnt.insert(abs(b));
        cnt.insert(abs(c));
        cnt.insert(abs(a+b));
        cnt.insert(abs(a+c));
        cnt.insert(abs(b+c));
        cnt.insert(abs(a-b));
        cnt.insert(abs(a-c));
        cnt.insert(abs(b-c));
        cnt.insert(abs(a+b+c));
        cnt.insert(abs(a+b-c));
        cnt.insert(abs(a+c-b));
        cnt.insert(abs(b+c-a));
        cnt.erase(0);
        return cnt.size();
    }
    int main()
    {
        int t,a,b,maxx;
        scanf("%d",&t);
        while(t--)
        {
            maxx=0;
            scanf("%d%d",&a,&b);
            for(int i=1;i<=a/2;i++)
            {
                maxx=max(cal(i,a-i,b),maxx);
            }
            for(int i=1;i<=b/2;i++)
            {
                maxx=max(cal(i,b-i,a),maxx);
            }
            printf("%d
    ",maxx);
        }
        return 0;
    }

    D题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3708

    题意:水题。公交路线的数量/公交车的数量,注意两点之间存在多条路线的话,只能算是一条。构图即可。

    #include<iostream>
    #include<string>
    #include<iomanip>
    #include<cstring>
    using namespace std;
    int a[505],b[505];
    int  map[505][505];
    int main()
    {
        int T,bus,m;
        cin>>T;
        while(T--)
        {
            cin>>bus>>m;
            memset(map,0,sizeof(map));
            int sum=0;
            for(int i=1;i<=m;i++)
            {
                cin>>a[i];
            }
            for(int i=1;i<=m;i++)
            {
                cin>>b[i];
            }
            for(int i=1;i<=m;i++)
            {
                if(map[a[i]][b[i]]||map[b[i]][a[i]])
                continue;
                else
                {
                    map[a[i]][b[i]]=1;
                 sum++;
               }
            }
            double ans;
            ans=sum*1.0/(bus*1.0);
            cout<<fixed<<setprecision(3)<<ans<<endl;
        }
        
    }

    F题:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3710

    题意是给你n个人,m对朋友关系,如果两个人的公共好友超过k人,那他们可以成为新的朋友,问经过一段“”足够长的时间后“, 新产生了多少对朋友关系?

    数据量比较小。暴力即可。遍历每对关系,如果他们之间的好友超过k,就将他们置为好友,然后从头继续扫描。一旦没有新的关系产生,结束,输出结果。

    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    using namespace std;
    bool map[105][105];
    bool vis[105],flags;
    int k,t,n,m,u,v;
    int sum,cnt;
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            cnt=0;
            scanf("%d%d%d",&n,&m,&k);
            memset(map,0,sizeof(map));
            for(int i=0;i<n;++i)
            {
                map[i][i]=1;
            }
            for(int i=1;i<=m;++i)
            {
                scanf("%d%d",&u,&v);
                map[u][v]=1;
                map[v][u]=1;
            }
            while(true)
            {
                flags=false;
                for(int i=0;i<n;++i)
                {
                    for(int j=0;j<n;++j)
                    {
                        if(map[i][j])
                        continue;
                        sum=0;
                        for(int ll=0;ll<n;++ll)
                        {
                            if(map[i][ll]&&map[ll][j])//求每对关系是不是满足>=4的时候,枚举中间点
                            {
                                sum++;
                                //cout<<i<<' '<<j<<' '<<ll<<endl;
                                if(sum>=k)
                                break;
                            }
                        }
                        if(sum>=k)
                        {
                            map[i][j]=1;
                            map[j][i]=1;
                            flags=true;
                            cnt++;
                        }
                    }
                }
                if(!flags)
                break;
            }
            printf("%d
    ",cnt);
        }
        return 0;
    }

    H:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3712

    水题,按照规则计分即可。贪心。

    #include<iostream>
    #include<string>
    #include<cstring>
    using namespace std;
    int main()
    {
        int a,b,c;
        int T;
        cin>>T;
        while(T--)
        {
            cin>>a>>b>>c;
            int max1=0,min1=0;
            int i=1;
            for(;i<=a;i++)
            {
                min1+=300*((i-1)*2+1);
            }
            for(;i<=a+b;i++)
            {
                min1+=100*((i-1)*2+1);
            }
            for(;i<=a+b+c;i++)
            {
                min1+=50*((i-1)*2+1);
            }
            
            for(int i=1;i<=c;i++)
            {
                max1+=50*((i-1)*2+1);
            }
            for(int j=c+1;j<=c+b;j++)
            {
                max1+=100*((j-1)*2+1);
            }
            for(int i=c+b+1;i<=a+b+c;i++)
            {
                max1+=300*((i-1)*2+1);
            }
            
            cout<<min1<<" "<<max1<<endl;
        }
        return 0;
    }

    I:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3713

    坑爹的题意。很难理解啊。输入的字符串中空格也要算到长度里面,先将串的长度换成二进制,取后七位(&127即1111111),然后如果前面还有1的话(没有的话就是0),再加一位最高位1(| 128即可),这样组成一个字节8位,依次循环。  处理完长度之后,将字符串的内容每一个字符的ASCII码按照十六进制输出即可。注意,空串的时候输出00。

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int main()
    {
        int n;
        cin>>n;
        getchar();
        while(n--)
        {
            string s;
            getline(cin,s);
            int len=s.length();
            if(len==0)
            {
                cout<<"00";
            }
            else
            {
            int temp=len;
            int cur=0;
            while(temp)
            {
                cur=temp&127;
                temp=temp>>7;
                if(temp)
                cur|=128;
                printf("%02X",cur);
            }
            
            for(int i=0;i<len;i++)
            {
                int op=s[i];
                printf("%02X",op);//控制输出位数,不足的话前面补0,X代表大写的十六进制
            }
            
            }
            cout<<endl;
        }
        return 0;    
    }

    J:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3714

    水题。在环形中取连续m个数的最大值,将数组复制加入后面相当于处理环形。

    #include<iostream>
    #include<string>
    using namespace std;
    int s[1000];
    int main()
    {
        int T,n,m;
        cin>>T;
        while(T--)
        {
            cin>>n>>m;
            for(int i=1;i<=n;i++)
            {
             cin>>s[i];
             s[i+n]=s[i];
            }
            int max1=-1;
            for(int i=1;i<=2*n-m;i++)
            {
                int sum=0;
                for(int j=i;j<i+m;j++)
                {
                    sum+=s[j];
                }
                if(sum>max1)
                max1=sum;
            }
            cout<<max1<<endl;
        }
        return 0;
    }

    K:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3715

    等待更新。。。

  • 相关阅读:
    人人都是 Serverless 架构师 | 现代化 Web 应用开发实战
    KubeDL HostNetwork:加速分布式训练通信效率
    独家下载!阿里云云原生携 10+ 技术专家带来《云原生与云未来的新可能》
    国内唯一!阿里云容器服务进入 Forrester 领导者象限
    函数abs的隐式声明 gcc5.1.0 Implicit declaration of function abs gcc5.1.0
    Vue Design Patterns All In One
    linux 中 tar.lzma 文件的解压、压缩
    linux 中删除除第一次匹配特定字符串所在行之外的所有行
    linux 系统中输出匹配特定字符至末尾的行
    根据位点的物理位置、重组率计算遗传距离
  • 原文地址:https://www.cnblogs.com/Tach-ac/p/4396973.html
Copyright © 2020-2023  润新知