PAT 1058 选择题

1058 选择题

批改多选题是比较麻烦的事情,本题就请你写个程序帮助老师批改多选题,并且指出哪道题错的人最多。

输入格式:

输入在第一行给出两个正整数 N(≤ 1000)和 M(≤ 100),分别是学生人数和多选题的个数。随后 M 行,每行顺次给出一道题的满分值(不超过 5 的正整数)、选项个数(不少于 2 且不超过 5 的正整数)、正确选项个数(不超过选项个数的正整数)、所有正确选项。注意每题的选项从小写英文字母 a 开始顺次排列。各项间以 1 个空格分隔。最后 N 行,每行给出一个学生的答题情况,其每题答案格式为 (选中的选项个数 选项1 ……),按题目顺序给出。注意:题目保证学生的答题情况是合法的,即不存在选中的选项数超过实际选项数的情况。

输出格式:

按照输入的顺序给出每个学生的得分,每个分数占一行。注意判题时只有选择全部正确才能得到该题的分数。最后一行输出错得最多的题目的错误次数和编号(题目按照输入的顺序从 1 开始编号)。如果有并列,则按编号递增顺序输出。数字间用空格分隔,行首尾不得有多余空格。如果所有题目都没有人错,则在最后一行输出 Too simple

输入样例:

3 4 
3 4 2 a c
2 5 1 b
5 3 2 b c
1 5 4 a b d e
(2 a c) (2 b d) (2 a c) (3 a b e)
(2 a c) (1 b) (2 a b) (4 a b d e)
(2 b d) (1 e) (2 b c) (4 a b c d)

输出样例:

3
6
5
2 2 3 4

自己第一次写的:我很奇怪,在测试里是全对的,但是提交后就只有两分,问题出在哪里目前还灭找到(加油找问题T_T)

#include <stdio.h>
#include <string.h>

typedef struct{
	int score;	//该题的总分 
	int xuan;	//选项个数 
	int zheng;	//选项正确个数 
	char right[20];//正确答案选项 
}Score;

int main(void){
	int n,m,i,j;
	scanf("%d %d",&n,&m);
	char answer[n][m][20];
	Score score[m];//m个题目的信息 
	int error[m],total[n];	//错题数  每个人的总分
	for(i=0;i<m;i++){
		error[i]=0;
	} 
	for(i=0;i<n;i++){
		total[i]=0;
	}
	//输入每个题目的信息
	char c;
	for(i=0;i<m;i++){
		scanf("%d %d %d",&score[i].score,&score[i].xuan,&score[i].zheng);
		getchar();
		for(j=0;(c=getchar())!='\n';j++){
            score[i].right[j]=c;
		}
		score[i].right[j]='\0';
	}
	 //输入学生的答案
	 for(i=0;i<n;i++){
	 	for(j=0;(c=getchar())!='\n';){
	 		if(c>='9' && c<='0'){
                getchar();
                scanf("%[^)]",answer[i][j++]);
            }	
		 }
	 }
	 
	 //开始对答案 
	 for(i=0;i<n;i++){
	 	for(j=0;j<m;j++){
	 		if(strcmp(answer[i][j],score[j].right)==0){//说明和答案一样,没有错误 
	 			total[i]+=score[i].score; 
			 } 
			 else{
			 	error[j]++;
			 }
		}
		printf("%d\n",total[i]);
	 }
	 
	 int max=0;//选取出最多错误次数的题目
	 for(i=0;i<m;i++){
	 	if(max<error[i]) max=error[i];
	 } 
	 
	 if(max==0)	printf("Too simple\n");
	 else{
	 	printf("%d",max);
	 	for(i=0;i<m;i++){
	 		if(error[i]==max){
	 			printf(" %d",i+1);
			 }
		 }
	 }
	 
	 return 0;
}

别人的代码:很巧妙的将每个选项以及不同选项的组合都用不同的数字表示了,这样就可以对照答案了(好好理解理解这个|= 和 <<操作)

#include <stdio.h>
typedef struct prods{
	int fenshu;//分数 
	int zheng;//正确 
	int fu;//错误 
}prod;
int read(){//阅读‘count option1.’格式,自定义函数 
	char c;
	int k,sam,ans=0;
	scanf("%d",&sam);
	for(k=0;k<sam;k++){
		while((c=getchar())==' ');
		ans |= 1 << (c-'a');// |=按位或后赋值,<<左移
	}
	return ans;
}
int main(){
	int n,m,i,j,max=0,user;
	scanf("%d %d",&n,&m);//阅读每个问题的答案 
	prod arr[100];
	for(i=0;i<m;i++){
		scanf("%d %d",&arr[i].fenshu,&user);
		arr[i].fu=0;
		arr[i].zheng=read();
	}
	for(i=0;i<n;i++){//阅读每个学生的答案 
		int daan=0;
		for(j=0;j<m;j++){//阅读一个问题的答案
			while(getchar()!='(');
			if(read()==arr[j].zheng)//如果是对的 
				daan=daan+arr[j].fenshu;
			else if(max< ++arr[j].fu)//如果大多数学生都错了
				max=arr[j].fu;
			while(getchar() != ')');
		}
		printf("%d\n",daan);
	}
	if(max==0){
		printf("Too simple");
	}else{
		printf("%d",max);
		for(i=0;i<m;i++){
			if(arr[i].fu==max){
				printf(" %d",i+1);
			}
		}
	}
	return 0;
}

这里https://www.cnblogs.com/gh110/p/12158191.html学到的

2022.7.6

还是没有写出来,努力学习,多抄几遍!

思路:核心问题就是输入的问题,只要能将答案完成的输入进去,在进行比较一下就行了

知识收获:

①移位:A<<B  左移   意思是 将A的二进制数后面添加B个0(右移同理)举例:A=3 B=2 

先将3转化成二进制11,然后在11后面加两个0,结果是1100,转化成十进制是12

②按位或: A|=B    将A和B的二进制数每个位相或,只要有1的位值就为1, 举例:8(1000二进制)7(111二进制)相或的结果是1111(二进制)转化成十进制数是15,如果是两个8按位相或 结果是(1000二进制)转化成十进制结果还是8

#include <stdio.h>

typedef struct prods{
	int fenshu;
	int zheng;
	int fu;
}prod;

int read(){
	char c;
	int k,sam,ans=0;
	scanf("%d",&sam);
	for(k=0;k<sam;k++){
		while((c=getchar())==' ');//过滤空格2
		ans|=1<<(c-'a');//先左移后按位 | 或 
	}
	
	return ans;
}

int main(void){
	int n,m,i,j,max=0,user;
	scanf("%d %d",&n,&m);
	prod arr[100];
	for(i=0;i<m;i++){
		scanf("%d %d",&arr[i].fenshu,&user);
		arr[i].fu=0;//初始化错题数为0
		arr[i].zheng=read();//使用read函数将正确答案赋值 
	}

	/*for(i=0;i<m;i++){
		printf("arr[%d]=%d\n",i,arr[i].zheng);
	}
	printf("\n");*/
	
	for(i=0;i<n;i++){
		int daan=0;
		for(j=0;j<m;j++){
			while(getchar()!='(');
			if(read()==arr[j].zheng)	daan+=arr[j].fenshu;
			else if(max<++arr[j].fu) max=arr[j].fu;
			while(getchar()!=')'); 
		}
		printf("%d\n",daan);
	} 
	
	if(max==0)	printf("Too simple\n");
	else {
		printf("%d",max);
		for(i=0;i<m;i++){
			if(arr[i].fu==max) printf(" %d",i+1);
		}
	}*/
	
	return 0; 
}

好好学习,天天向上!
我要考研!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值