PAT (Basic Level) Practice (中文)1058 选择题 (20 分)

文章目录

  • PAT (Basic Level) Practice (中文)1058 选择题 (20 分)
    • 题目描述:
    • 输入格式:
    • 输出格式:
    • 输入样例:
    • 输出管理:
    • 题目要求:
    • 解题思路:
    • 完整代码:

题目描述:

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

输入格式:

输入在第一行给出两个正整数 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

题目要求:

作者           CHEN, Yue
单位           浙江大学
代码长度限制     16 KB
时间限制        400 ms
内存限制        64 MB

解题思路:

事实证明,题目剪短的题,反而往往没有那么简单!

1、首先是需要能够将 m 行输入进行存储,我在这里又使用了 struct 结构体

这里我经过思考再三,在存储正确答案的选项个数和其具体的选项时,没有按照常规的方法去存,而是将其看成一个整体的字符串!

// 例如:样例中 2 a c 是正确答案的个数和具体选项,那我存储的正确答案就是字符串 "2 a c"
typedef struct problem{int num ;            // 题号 int chooseN;      // 选项个数 int score;          // 这一题的满分值 string ans="" ;     // 正确答案 int wrong = 0 ;     // 错误人数
}Problem;// 以及对应的输入控制
for(int i = 0 ; i < m ; i ++){pro[i].num = i + 1;   // 题号从 1 开始cin >> pro[i].score >> pro[i].chooseN  ; // 先存储该题的 满分值 score 和 选项个数 chooseNgetline(cin , pro[i].ans) ; // 存储从 chooseN 之后的整行数据,对比样例知,其第一个字符为空格pro[i].ans = (pro[i].ans).substr(1,(pro[i].ans).length() - 1) ;   //去掉其首个空格字符
}// PS:  这里的输入用 scanf() 函数应该会比较好操作一点,就不用进行字符串的切割。

2、接下来就是本题的重难点了,就是如何根绝每个同学的每一题的答案,进行批改,并统计每一题错误人数。

样例中每一题的答案均用 () 扩住了,且每一项之间都有空格 (这也是为什么我会选择正确答案存储之时存储空格的原因)

/*首先要抉择是怎么拿到该学生每一题的输入选项,利用 scanf() 的话,每个人的输入需要分成好几部分来计算,显得复杂,且可读性不高所以我和输入的时候,选择了一致的 getline() 函数,直接拿到该同学所有题目的答案
*/
getline(cin , str) ; // 上面说那么多,其实就是这一句代码/*然后我们需要做的就是,把每一题的学生选的答案给它整出来既然每一题的答案都用 () 作为开始和结束,那我们找到 ( 和 ) 的位置,直接对字符串进行 substr 就好啦说干就干!
*/
vector<string> row ; // 用来存每题输入的答案的 vector
int j = 0 , k = 0 ;
while( j < str.length()){if(str[j] == '('){ // 找到 ( 的时候,继续查找其后最接近的 )while(k++ <str.length()){if(str[k] == ')'){// 从 j + 1 号位置开始 ,长度为 k - j - 1 的子串,就是我们需要的学生答案!row.push_back(str.substr(j + 1 , k - j - 1)) ; // 加入 vector 中j += k - j - 1 ; // 加上这一行是减少第一层 while 的次数 (不加也能 AC )break ;}}}j ++;
}/*然后就是简单的匹配一下答案是否正确啦,正确就该同学的总分加上这题的满分,错误就该题的错误人数加 1
*/
// 记录该同学的总分
int sum = 0 ;
for(int i = 0 ; i < row.size() ; i ++){if(row[i] == pro[i].ans)sum += pro[i].score ;elsepro[i].wrong ++ ;
}
//  输出该同学的总分
cout<<sum<<endl;   /*最后的最后就是输出一下,错误最多的题号啦, 我就是喜欢 sort 函数 (菜鸡只会这个)
*/
bool cmp(Problem a , Problem b){if(a.wrong == b.wrong) return a.num < b.num ;  // 错误人数相同时,按题号升序排列return a.wrong > b.wrong ;  // 错误人数不同时,按错误人数降序排列
}
sort(pro , pro + m , cmp) ; // 输出就看完整代码了……

完整代码:

#include<bits/stdc++.h>
using namespace std ;
#define MAX 110
typedef struct problem{int num ;    // 题号 int chooseN ; // 选项个数 int score ;     // 这一题的满分值 string ans = "" ; // 正确答案 int wrong = 0 ;// 错误人数
}Problem ;
Problem pro[MAX] ;
bool cmp(Problem a , Problem b){if(a.wrong == b.wrong) return a.num < b.num ;return a.wrong > b.wrong ;
}
int main(){int n , m ;cin >> n >> m ;for(int i = 0 ; i < m ; i ++){pro[i].num = i + 1 ;cin >> pro[i].score >> pro[i].chooseN  ;getline(cin , pro[i].ans) ;pro[i].ans = (pro[i].ans).substr(1,(pro[i].ans).length() - 1) ;
//      getline(cin , s) ;// 吸收回车    }string str ;
//  for(int i = 0 ; i < m ; i ++){//      cout<<pro[i].num<<pro[i].score << pro[i].chooseN << "|" << pro[i].ans<<"|"<<endl;
//  }
//  getline(cin , str) ;// 吸收回车 for(int i = 0 ; i < n ; i ++){getline(cin , str) ;vector<string> row ;int j = 0 , k = 0 ;while( j < str.length()){if(str[j] == '(' ){while( k ++ < str.length()){if(str[k] == ')'){row.push_back(str.substr(j + 1 , k - j - 1 )) ;j += k - j - 1 ;break ;}}}j ++ ;   }int sum = 0 ;// 该同学的总分 for(int i = 0 ; i < row.size() ; i ++){//          cout<<"|"<<row[i]<<"|"<<endl;if(row[i] == pro[i].ans)sum += pro[i].score ;elsepro[i].wrong ++ ;}cout << sum << endl ;  //  输出该同学的总分 } sort(pro , pro + m , cmp) ;if(pro[0].wrong){cout<<pro[0].wrong<<" "<<pro[0].num ; for(int i = 1 ; i < m ; i++){if(pro[i].wrong != pro[0].wrong)break ;elsecout<<" "<<pro[i].num ;}cout<<endl ;}else cout<<"Too simple"<<endl ;return 0 ;
}

PAT (Basic Level) Practice (中文)1058 选择题 (20 分)相关推荐

  1. PTA平台 · PAT(Basic Level) Practice(中文) 题目集

    前  言 ※  PTA是 程序设计类实验辅助教学平台 ,里边包含一些编程题目集以供练习. ※  PAT是 浙江大学计算机程序设计能力考试(Programming Ability Test),分为乙级( ...

  2. 【PAT (Basic Level) 】1028 人口普查 (20 分)

    某城镇进行人口普查,得到了全体居民的生日.现请你写个程序,找出镇上最年长和最年轻的人.这里确保每个输入的日期都是合法的,但不一定是合理的--假设已知镇上没有超过 200 岁的老人,而今天是 2014 ...

  3. 【PAT (Advanced Level) Practice】1008 Elevator (20 分)

    #include<iostream> #include<cstdio> #include<cstdlib> #include<string> #incl ...

  4. PAT (Basic Level) Practice (中文)答案合集

    准备复试专用,目标刷完全部中文题! 1001 害死人不偿命的(3n+1)猜想 (15 分) 卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 ...

  5. 1048 数字加密【PAT (Basic Level) Practice (中文)】

    1048 数字加密[PAT (Basic Level) Practice (中文)] 原题链接:1048 数字加密 (pintia.cn) 1.前言 PAT(乙级)2015年冬季考试 第三题 分数: ...

  6. PAT (Basic Level) Practice (中文)题目集合

    1001 害死人不偿命的(3n+1)猜想 (15 分) #include<bits/stdc++.h> using namespace std;int n, ans; int main() ...

  7. 1001 害死人不偿命的(3n+1)猜想 (15分) PAT (Basic Level) Practice (中文)C语言版

    PAT (Basic Level) Practice (中文) 1001 害死人不偿命的(3n+1)猜想 (15分) 卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一 ...

  8. PAT (Basic Level) Practice (中文)1095 解码PAT准考证 (25 分)

    PAT (Basic Level) Practice (中文)1095 解码PAT准考证 (25 分) PAT 准考证号由 4 部分组成: 第 1 位是级别,即T代表顶级:A代表甲级:B代表乙级: 第 ...

  9. PAT (Basic Level) Practice (中文)1070 结绳 (25 分) 凌宸1642

    PAT (Basic Level) Practice (中文)1070 结绳 (25 分) 凌宸1642 题目描述 给定一段一段的绳子,你需要把它们串成一条绳.每次串连的时候,是把两段绳子对折,再如下 ...

最新文章

  1. 如何在FBL5N中增加所需字段
  2. php+mysql+html 之页面输入、输出
  3. Ubuntu的网络设置
  4. linux命令-- pstack命令(跟踪进程栈)
  5. Android系统KeyStore (AndroidKeyStore): 存储密钥
  6. H5页面关于android软键盘弹出顶起底部元素的解决方案
  7. html cdn不缓存,【前端开发日常 - 6】七牛CDN上的网页缓存问题及HTML禁止缓存(续)...
  8. 英语面试功略:英语口语突击法
  9. cfe刷机教程 斐讯k3_小白专属------K3官方固件CFE刷LEDE教程
  10. 景深 (摄影测量与遥感学术语)
  11. 两部手机怎样才能把数据都传过来_两个手机如何互传照片、文件 ,教你四大绝招...
  12. 使用C++编写卷积神经网络(一)
  13. 网络服务(5)——usb网卡名称修改(RK3399 Ubuntu)
  14. 突破限制轻松下载网盘的文件,免登陆使用,速度也不错!
  15. 《构建之法》读书笔记(2)
  16. 测试计算机病毒,计算机病毒测试
  17. java基础练习实例_java基础练习题(se)
  18. 创业者能从猎豹移动身上取到哪些经?
  19. 通达信指标加密保护方法
  20. python的opencv使用总结

热门文章

  1. 天津椭圆曲线科技(原木姜子科技)市集商城代码开源
  2. 移动硬盘格式化后数据怎么恢复
  3. kafka虞兮叹二(生产消息不丢失不重复)
  4. Ubuntu:u盘作系统启动盘
  5. 【方向盘】Spring Boot 2.6.0正式发布,循环引用终于被禁
  6. 横线从文字中间穿过的CSS效果属性和html标签
  7. webpack bulid后时,网页白屏,报错:导入的资源文件路径不对
  8. 任务调度神器 airflow 之初体验
  9. Flask有线打印机转无线打印机(电脑和手机)
  10. Source Insight配置文件