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;
}
好好学习,天天向上!
我要考研!