问题 A: 比赛排名
题目描述
今天你们集训队打了一场比赛,你发现它和你之前打的比赛不一样
比赛一共三道题目:A,B,C。首先,总分越高排名越高,但是其中A题很难,所以如果两个人总分相同,如果一个人A题拿到的分数比较高,那么他的排名就会比总分相同的另一个人高。如果两人总分相同且A题分数也相同,那么越早加入集训队的排名越高。
陈老师请你帮他统计这场比赛排名最高的5位同学,你和排名最高的5位同学都可以得到陈老师精选的一套题作为奖励。
输入
输入文件为“sort.in”
第1行为一个正整数n,表示你们集训队的学生人数。
第2到n+1行,每行有3个用空格隔开的数字,每个数字都在0到100之间。第j行的3个数字依次表示第j-1个加入集训队的学生在这次比赛中的A、B、C三题的分数。每个学生的加入集训队的次序按照输入顺序编号为1~n(恰好是输入数据的行号减1)。
所给的数据都是正确的,不必检验。
输出
输出文件为“sort.out”
输出5行
每行是两个用空格隔开的正整数 依次表示前5名学生加入集训队的次序和总分。
样例输入
6
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98
样例输出
6 265
4 264
3 258
2 244
1 237
提示
【数据范围】
50%的数据满足:各学生的总成绩各不相同
100%的数据满足:6<=n<=300
题解:按题意排序
代码:
#include <bits/stdc++.h>
using namespace std;
struct node
{
int mark1;
int mark2;
int mark3;
int tim;
int sum;
}s[305];
int comp(node a,node b)
{
if(a.sum<b.sum)
{
swap(a,b);
return 0;
}
else if((a.sum==b.sum)&&(a.mark1<b.mark1))
{
swap(a,b);
return 0;
}
else
swap(a,b);
}
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s[i].mark1>>s[i].mark2>>s[i].mark3;
s[i].tim=i;
s[i].sum=s[i].mark1+s[i].mark2+s[i].mark3;
}
sort(s+1,s+1+n,comp);
for(int i=1;i<=5;i++)cout<<s[i].tim<<" "<<s[i].sum<<endl;
return 0;
}
问题 B: 找队友
题目描述
陈老师想要所有集训队成员进行一场特别的比赛,以前我们打比赛都是各打各的,今天可以让大家找一个队友,两个人组队进行比赛。
我们给所有人评估一个能力值,并规定组队的两个人的能力值之和不能超过给定的值w,防止某个队太强碾压其他队,所以太强的人可能没办法和别人组队,只能自己一个人一队,这可能就是强者的寂寞吧。
陈老师希望队伍数量尽可能少,现在问你最少的队伍数是多少?
输入
输入文件为“friend.in”
第1行包括一个整数w,两两组队的人能力值之和的上限。
第2行为一个整数n,表示集训队总人数。
第3~n+2行每行包含一个正整数pi (5 <= pi <= w),表示对应队员的能力值。
输出
输出文件为“friend.out”
输出一行
包含一个整数,即最少的队伍数量。
样例输入
100
9
90
20
20
30
50
60
70
80
90
样例输出
6
提示
【数据范围】
50%的数据满足:1 <= n <= 15
100%的数据满足:1 <= n <= 30000 80 <= w <= 200
题解:此题的输入输出样例竟然和纪念品分组是一样的!!
一道贪心,排序即可
代码:
#include<bits/stdc++.h>
using namespace std;
int p[30005];
int main()
{
int w,n;
int ans=0;
cin>>w>>n;
for(int i=1;i<=n;i++)
cin>>p[i];
sort(p+1,p+1+n);
for(int j=n,i=1;i<=j;j--)
{
if(p[i]+p[j]<=w)
{
ans++;
i++;
}
else ans++;
}
cout<<ans<<endl;
return 0;
}
问题 C: 作文标题
题目描述
【题目描述】
陈老师让你写一篇作文,结果你写的文章字数不够,你在原来标题(原来标题都是有效字符,包括大小写英文字母,数字字符)中加入大量无效字符(包括空格和换行符)来凑数,但是你的伎俩被老师发现了,老师让你求原来标题的字符数。
输入
输入文件为“char.in”
输入一个字符串s
输出
输出文件为“char.out”
输出一行
包含一个整数,即原来作文标题的字符数(不含空格和换行符)。
样例输入
【样例输入1】
234
【样例输出2】
Ca 45
样例输出
【样例输出1】
3
【样例输出2】
4
提示
【数据范围】
记L为s的长度
50%的数据满足:1 <= L<= 100
100%的数据满足:1 <= L <= 100000
题解:注意用gets读入
代码:
#include<bits/stdc++.h>
using namespace std;
char a[100005];
int main()
{
gets(a);
int len=strlen(a);
int ans=0;
for(int i=0;i<len;i++)
{
if('A'<=a[i]&&a[i]<='Z'||'a'<=a[i]&&a[i]<='z'||'0'<=a[i]&&a[i]<='9')
ans++;
}
cout<<ans<<endl;
}
问题E: 工作分配
题目描述
你终于当上了tx公司里的一个组长。现在你的领导给了你一个任务,你需要把这个工作分解分配给你的组员。你已经分解好了任务,分成了n个工作,你手下有n个人,将工作i分配给第j个人所需的费用为c[i][j]。试设计一个算法,为每一个人都分配一件不同的工作,并使总费用达到最小,并输出最小的总费用。
输入
输入文件为“leader.in”
第一行有1个正整数n。接下来的n行,每行n个数,第i行表示第i个人各项工作费用。
输出
输出文件为“leader.out”
输出计算出的最小总费用
样例输入
3
4 2 5
2 3 6
3 4 5
样例输出
9
提示
【数据范围】
对于100%的数据,1 ≤ n ≤ 20
题解:回溯
代码:
#include<bits/stdc++.h>
using namespace std;
int n;
int c[21][21],vis[21];
int best=INT_MAX;
int sum=0;
void search(int dep)
{
if(dep==n+1)
{
best=min(sum,best);
return;
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
vis[i]=true;
sum+=c[dep][i];
if(sum<best)search(dep+1);
sum-=c[dep][i];
vis[i]=false;
}
}
}
int main()
{
cin>>n;
memset(vis,false,sizeof(vis));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>c[i][j];
search(1);
cout<<best<<endl;
}