目录
质数筛[P5736]
题目描述
输入 n 个不大于 10^5 的正整数。要求全部储存在数组中,去除掉不是质数的数字,依次输出剩余的质数。
输入格式
第一行输入一个正整数 n,表示整数个数。
第二行输入 n 个正整数 a,以空格隔开。
输出格式
输出一行,依次输出剩余的质数,以空格隔开。
样例
-
样例输入
5
3 4 5 6 7
-
样例输出
3 5 7
提示
数据保证,1<= n <=100,1 <= a <=10^5。
思路:首先需要输入n及n个数,然后再一一判断是否为质数,是质数的输出,不是的不输出。那可以将数字存进数组,再对数组进行遍历即可。可以先判断哪些是质数(不是的改为0),再输出(0不输出);也可以边判断边输出。
#include<stdio.h>
#include<math.h>
int prime_number(int a){
if(a==2) return 1;
else if(a==3) return 1;
else if(a==1) return 0;
for(int i = 2;i<=sqrt(a);i++)
if(a%i==0) return 0;
return 1;
}
void print_number(int *p,int n){
int kase = 1;
for(int i = 0;i<n;i++)
if(prime_number(*(p+i))&&kase){
printf("%d",*(p+i));
kase = 0;
}
else if(prime_number(*(p+i))&&!kase)
printf(" %d",*(p+i));
}
int main()
{
int n;
scanf("%d",&n);
int a[n];
for(int i = 0;i<n;i++)
scanf("%d",&a[i]);
print_number(a,n);
return 0;
}
歌唱比赛[P5738]
题目描述
有n(n <= 100)名同学参加歌唱比赛,并接受 m(m <= 20) 名评委的评分,评分范围是 0 到 10 分。这名同学的得分就是这些评委给分中去掉一个最高分,去掉一个最低分,剩下 (m-2) 个评分的平均数。请问得分最高的同学分数是多少?评分保留 2 位小数。
输入格式
第一行两个整数 n,m。
接下来 n 行,每行各 m 个整数,表示得分。
输出格式
输出分数最高的同学的分数,保留两位小数。
样例
-
样例输入
7 6
4 7 2 6 10 7
0 5 0 10 3 10
2 6 8 4 3 6
6 3 6 7 5 8
5 9 3 3 8 1
5 9 9 3 2 0
5 8 0 4 1 10
-
样例输出
6.00
思路:首先输入人数和评委数。那用二维数组来处理:每一行都为对应选手的评委评分。然后可以求出每个选手自己的总分,再减去最高和最低分。因为每个人都有m个评分,那么只需要比较求平均值之前的数值也可以得到最高分,输出的时候再除以(m-2即可(也可以先求出平均分,最后比较输出最高平均分)。
#include<stdio.h>
int min_search(int a[],int m){
int minn = 11;
for(int i = 0;i<m;i++)
if(minn>a[i]) minn = a[i];
return minn;
}
int max_search(int *p,int m){
int maxn = -1;
for(int i = 0;i<m;i++)
if(maxn<p[i]) maxn = p[i];
return maxn;
}
int add(int *p,int m){
int sum = 0;
for(int i = 0;i<m;i++)
sum+=*(p+i);
return sum;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int a[n][m],b[n];
for(int i = 0;i<n;i++)
for(int j = 0;j < m;j++)
scanf("%d",&a[i][j]);
for(int i = 0;i<n;i++){
int sum = add(a[i],m);
int minn = min_search(a[i],m);
int maxn = max_search(a[i],m);
b[i] = sum - minn - maxn;
// printf("\n**%d %d %.2lf\n",i,b[i],1.0*b[i]/(m-2));
}
int maxn = max_search(b,n);
printf("%.2lf",1.0*maxn/(m - 2));
return 0;
}
旗鼓相当的对手 - 加强版[P5741]
题目描述
现有 N 名同学参加了期末考试,并且获得了每名同学的信息:姓名(没有空格)、语文、数学、英语成绩。如果某对学生 < i , j > 的每一科成绩的分差都不大于 5,且总分分差不大于 10,那么这对学生就是“旗鼓相当的对手”。现在我们想知道这些同学中,哪些是“旗鼓相当的对手”?请输出他们的姓名。
所有人的姓名是按照字典序给出的,输出时也应该按照字典序输出所有对手组合。也就是说,这对组合的第一个名字的字典序应该小于第二个;如果两个组合中第一个名字不一样,则第一个名字字典序小的先输出;如果两个组合的第一个名字一样但第二个名字不同,则第二个名字字典序小的先输出。
输入格式
第一行输入一个正整数 N,表示学生个数。
第二行开始,往下 N 行,对于每一行首先先输入一个字符串表示学生姓名,再输入三个自然数表示语文、数学、英语的成绩。均用空格相隔。
输出格式
输出若干行,每行两个以空格隔开的字符串,表示一组旗鼓相当的对手。注意题目描述中的输出格式。
样例
-
样例输入
3
fafa 90 90 90
lxl 95 85 90
senpai 100 80 91
-
样例输出
fafa lxl
lxl senpai
提示
数据保证:1 <= N <=1000,姓名为长度不超过 8 的字符串,语文、数学、英语成绩均为不超过 150 的自然数。
思路:首先可以知道,需要定义一个由名字、语数英三科成绩四部分构成的结构体。输入n之后n行都要输入每个人的名字和成绩,那么可以考虑结构体数组,将每个学生的成绩存起来,方便处理。同时还需要定义一个用来比较二者是否“旗鼓相当”的函数。那么大抵流程就是:
输入 -> 计算个人总分 -> 循环比较是否“旗鼓相当” ->如果是则按照要求输出
#include<stdio.h>
#include<string.h>
#include<math.h>
struct grade{
char name[10];
int Ch;
int Ma;
int En;
};
int cmpare(struct grade a,struct grade b,int sum1,int sum2){
if(abs(a.Ch - b.Ch)<=5&&abs(a.En - b.En)<=5&&abs(a.Ma - b.Ma)<=5&&abs(sum1 - sum2)<=10)
return 1;
return 0;
}
int main()
{
int n,t;
scanf("%d",&n);
struct grade stu[n];
int sum[n];
memset(sum,0,sizeof(sum));
//输入
for(int i = 0;i<n;i++){
scanf("%s %d %d %d",stu[i].name,&stu[i].Ch,&stu[i].Ma,&stu[i].En);
sum[i]+=stu[i].Ch+stu[i].Ma+stu[i].En;
}
//比较
for(int i = 0; i<n;i++){
for(int j = i+1;j<n;j++){
if(cmpare(stu[i],stu[j],sum[i],sum[j]))
strcmp(stu[i].name,stu[j].name)<0?printf("%s %s\n",stu[i].name,stu[j].name):printf("%s %s\n",stu[j].name,stu[i].name);
}
}
return 0;
}
输出时要求按照字典序输出,那么可以通过strcmp(str1,str2)来实现,当前者字典序更靠前的时候,该函数的返回值小于零。