浙江省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\n",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\n",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

等待更新。。。

时间: 2024-10-31 01:38:17

浙江省10th程序设计竞赛部分题解的相关文章

福州大学第十届程序设计竞赛 -- 部分题解

题目传送:福州大学第十届程序设计竞赛 Problem A 神庙逃亡 水题 AC代码: #include<cstdio> #include<cmath> #include<iostream> using namespace std; int s, h, vx, vy; int main() { int w; cin >> w; while(w--){ cin >> s >> h >> vx >> vy; long

东南大学第十三届程序设计竞赛初赛题解

问题 A: 天梯评分系统 题目描述 在一个下雨的日子,沈学姐和四个好基友约定无事一同打dota(dota是一个5对5的MOBA类游戏)因为想证明谁最NB,他们就全部注册新号去爬天梯了.天梯有一套完整的评分系统,它可以根据每位选手每局的数据进行评分,因为dota的英雄既有辅助又有ganker还有后期,所以不同的英雄的评分标准不一样.可惜那天天梯服务器维护,无法进行评分.于是,他们记录下每一局的数据,找你来帮忙,希望你能够帮他们仿照天梯编一个评分系统,以便于他们比较谁是真正的神牛. 已知对于每个账号

2017年“达内杯”台州学院第十届大学生程序设计竞赛 非官方题解

感谢crq兄弟搞了这次校赛,让我认识到了自己傻的时候确实傻的可爱.crq棒棒哒,我们OJ也十年多了,不容易啊.大家能用得上的时候确实要练好基本功啊. 5259: 多项式值统计   Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByteTotal Submit: 316            Accepted:35 Description 形如anxn+an-1xn-1+-+a2x2 +a1x +a0的多项式称为一元多项式

第三届H-star 程序设计竞赛初赛题解

1.剪纸片:这是一道简单的题目,假如你身边有一张纸,一把剪刀,在H-star的比赛现场,你会这么做:(1). 将这张纸剪成两片(平行于短边剪开):(2)将其中一片剪成一个圆,作为圆柱的底面:(3) 纸的另一片的一边沿着圆的周长将圆围起来,直到围成一圈,形成一个无盖的圆柱体.需要注意的是,纸片可能会有重叠部分.聪明的你机智的你喜欢思考的你这时候就开始想,一张纸片按上述方式所组成的圆柱的最大体积是多少呢?请你用编程解决这个问题. 输入 输入第一行包含一个数字t代表接下来有t组数据: 接下来的t行,输

hdu 计算机学院大学生程序设计竞赛(2015’11)

搬砖 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 5134    Accepted Submission(s): 1288 Problem Description 小明现在是人见人爱,花见花开的高富帅,整天沉浸在美女环绕的笙歌妙舞当中.但是人们有所不知,春风得意的小明也曾有着一段艰苦的奋斗史. 那时的小明还没剪去长发,没有信用卡没有她

POJ 3420 Quad Tiling 题解 《挑战程序设计竞赛》

POJ 3420 Quad Tiling贴瓷砖:4*N的地板上用2*1的瓷砖铺满,求所有方案数对M求余.3.4熟练掌握动态规划矩阵的幂久违地上了节课,太无聊,只好刷一题.假设S[n]表示填满n时的方案数,有S[0]=1.定义矩阵M[p][q] := 边缘p和边缘q可以拼合时取1,否则取0所谓的可以拼合表示,两个边缘拼起来后长度为1(为2就拼接不起来了),且内部缝隙可以用2*1的瓷砖填满.那么M就有一些简单的性质了,比如M的第一行应该是:0 0 0 0 0 0... 继续阅读:码农场 » POJ

POJ 3411 Paid Roads 题解 《挑战程序设计竞赛》

POJ 3411 Paid Roads开路:N个城市间有m条单向路,分别从a到b,可以在c处交P路费,也可以直接交R路费.那么问题来了,你的挖掘机怎么开最省钱?3.4熟练掌握动态规划状态压缩DP乍一看可以Dijkstra,实际上的确可以Dijkstra.不过多了一个预交费的c,所以在遍历的时候多了一维状态,这个维度储存当前走过的城市集合.在Dijkstra的时候,如果走过了c那么就有两个选择,选其中最省的即可:否则没得选.#include <iostream> #include&nb.

“亚信科技杯”南邮第七届大学生程序设计竞赛之网络预赛 (部分题解)

“亚信科技杯”南邮第七届大学生程序设计竞赛之网络预赛 F 自动售货机 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte总提交 : 60            测试通过 : 13  题目描述 教学楼有一台奇怪的自动售货机,它只售卖一种饮料,单价5元,并且只收5元.10元面值的货币,但是同学们都很喜欢喝.这个售货机里没有多余的找零,也就是说如果一个持有10元的同学第一个购买,则他不能获得5元找零,但是如果在他之前有一个持有5

《ACM国际大学生程序设计竞赛题解Ⅰ》——基础编程题

这个专栏开始介绍一些<ACM国际大学生程序设计竞赛题解>上的竞赛题目,读者可以配合zju的在线测评系统提交代码(今天zoj貌似崩了). 其实看书名也能看出来这本书的思路,就是一本题解书,简单暴力的通过题目的堆叠来提升解决编程问题的能力. 那么下面开始探索吧. zoj1037: BackgroundFor years, computer scientists have been trying to find efficient solutions to different computing p