week2实验
题目一:化学
问题描述
化学很神奇,以下是烷烃基。
假设如上图,这个烷烃基有6个原子和5个化学键,6个原子分别标号1~6,然后用一对数字 a,b 表示原子a和原子b间有一个化学键。这样通过5行a,b可以描述一个烷烃基
你的任务是甄别烷烃基的类别。
Input
输入第一行为数据的组数T(1≤T≤200000)。每组数据有5行,每行是两个整数a, b(1≤a,b≤6,a ≤b)
数据保证,输入的烷烃基是以上5种之一
Output
每组数据,输出一行,代表烷烃基的英文名
Example
Input
2 1 2 2 3 3 4 4 5 5 6 1 4 2 3 3 4 4 5 5 6
Output
n-hexane 3-methylpentane
题意解析
该题事实上就是寻找特征来区分这五种烷烃,选择的区分特征不同会导致做法区分度很大。
做法
我个人把每个碳原子看作是一个点,利用点的度数来区分不同烷烃。
最大度数为2的烷烃即为n-hexane
最大度数为4的烷烃即为2,2-dimethylbutane
有两个度数为3的点的烷烃即为2,3-dimethylbutane
剩余两种不好区分,需要另外判断。
我区分剩余两类的方法是判断与它们相邻的点的度数。
对于2methylpentane,它与两个度数为1的点和一个度数为2的点相邻。
对于3methylpentane,它与一个度数为1的点和两个度数为2的点相邻。
可以直接统计与它们相邻的度数为1的点的个数来区分这两类。
代码
#include <iostream> #include <cstring> #include <algorithm> using namespace std; /* run this program using the console pauser or add your own getch, system("pause") or input loop */ int c[7][7]; int main(int argc, char** argv) { int numble; cin>>numble; for(int i=0;i<numble;i++) { for(int j=1;j<=6;j++) for(int t=1;t<=6;t++) { c[j][t]=0; } for(int j=1;j<=5;j++) { int a,b; cin>>a>>b; c[a][b]=1; c[b][a]=1; } int tem[7]={0}; int ttem[7]={0}; for(int j=1;j<=6;j++) for(int t=1;t<=6;t++) { //cout<<c[j][t]<<" "; if(c[j][t]) { tem[j]++; ttem[j]++; } } sort(tem,tem+7); if(tem[6]==2) cout<<"n-hexane"<<endl; else if(tem[6]==4) cout<<"2,2-dimethylbutane"<<endl; else if((tem[6]==3)&&(tem[5]==3)) cout<<"2,3-dimethylbutane"<<endl; else { int one[3];//记录只连1个的原子 int three;//记录3原子 int tt=0; for(int j=1;j<=6;j++) { if(ttem[j]==1) { one[tt]=j; tt++; } else if(ttem[j]==3) three=j; } //cout<<tt<<endl; int numble=0;//记录相邻的一原子数 for(int j=1;j<=6;j++) { if(c[three][j]==1) { for(int t=0;t<3;t++) { if(j==one[t]) { numble++; break; } } } } if(numble==2) cout<<"2-methylpentane"<<endl; else cout<<"3-methylpentane"<<endl; } } return 0; }
题目二:大力出奇迹
程序设计思维作业和实验使用的实时评测系统,具有及时获得成绩排名的特点,那它的功能是怎么实现的呢?
我们千辛万苦怼完了不忍直视的程序并提交以后,评测系统要么返回AC,要么是返回各种其他的错误,不论是怎样的错法,它总会给你记上一笔,表明你曾经在这儿被坑过,而当你历经千辛终将它AC之后,它便会和你算笔总账,表明这题共错误提交了几次。
在岁月的长河中,你通过的题数虽然越来越多,但通过每题时你所共花去的时间(从最开始算起,直至通过题目时的这段时间)都会被记录下来,作为你曾经奋斗的痕迹。特别的,对于你通过的题目,你曾经的关于这题的每次错误提交都会被算上一定的单位时间罚时,这样一来,你在做出的题数上,可能领先别人很多,但是在做出同样题数的人中,你可能会因为罚时过高而处于排名上的劣势。
例如某次考试一共八道题(A,B,C,D,E,F,G,H),每个人做的题都在对应的题号下有个数量标记,负数表示该学生在该题上有过的错误提交次数但到现在还没有AC,正数表示AC所耗的时间,如果正数a跟上了一对括号,里面有个正数b,则表示该学生AC了这道题,耗去了时间a,同时曾经错误提交了b次。例子可见下方的样例输入与输出部分。
Input
输入数据包含多行,第一行是共有的题数n(1≤n≤12)以及单位罚时m(10≤m≤20),之后的每行数据描述一个学生的信息,首先是学生的用户名(不多于10个字符的字串)其次是所有n道题的得分现状,其描述采用问题描述中的数量标记的格式,见上面的表格。
Output
根据这些学生的得分现状,输出一个实时排名。实时排名显然先按AC题数的多少排,多的在前,再按时间分的多少排,少的在前,如果凑巧前两者都相等,则按名字的字典序排,小的在前。每个学生占一行,输出名字(10个字符宽),做出的题数(2个字符宽,右对齐)和时间分(4个字符宽,右对齐)。名字、题数和时间分相互之间有一个空格。数据保证可按要求的输出格式进行输出。
Sample Input
8 20 GuGuDong 96 -3 40(3) 0 0 1 -8 0 hrz 107 67 -3 0 0 82 0 0 TT 120(3) 30 10(1) -3 0 47 21(2) -2 OMRailgun 0 -99 -8 0 -666 -10086 0 -9999996 yjq -2 37(2) 13 -1 0 113(2) 79(1) -1 Zjm 0 0 57(5) 0 0 99(3) -7 0
Sample Output
TT 5 348 yjq 4 342 GuGuDong 3 197 hrz 3 256 Zjm 2 316 OMRailgun 0 0
题意解析
事实上这个题的确是相当的“大力出奇迹”的题目,读入数据,然后排序。
排序部分很简单,问题是如何读入数据。
做法
我选择使用结构体存储每个学生的信息,包括姓名、字典序(事实上这没有必要,string比较时本身就是按照字典序比较,然而当时的我并不知道这一点)、做对的题目数量、时间分。在读入时就直接把做对的题目数和时间分算出来。
读数时主要是读入那些带()的数据,我选择将数据全部作为string读入,然后找出“(”和“)”的位置,将两个符号中间的字符转化为数字。string的find方法可以较为方便的解决这个问题。
排序过程是一个简单的桶排序,先进行不重要的排序,然后一直到最重要的排序。
代码
#include <iostream> #include <cstring> using namespace std; struct student{ string name;//姓名 int zidianxu; int timu;//题目数量 int time;//时间分 student() { name=""; timu=0;time=0;zidianxu=0; } }; student s[1000]; /* run this program using the console pauser or add your own getch, system("pause") or input loop */ int main(int argc, char** argv) { int a,b;//a为题目,b为罚时 cin>>a>>b; string tname; int numble=0; while(cin>>tname) { s[numble].name=tname; int tsum=0; for(int i=0;i<tname.length();i++) { tsum=tsum*10+int(tname[i]); } for(int i=0;i<a;i++) { string ts; cin>>ts; if((ts[0]=='-')||(ts[0]=='0')) continue; int judge=ts.find("("); if(judge==string::npos)//搜不到,一次过 { int sum=0; s[numble].timu++; for(int j=0;j<ts.length();j++) { int tt=int(ts[j])-48; sum=sum*10+tt; } s[numble].time=s[numble].time+sum; } else//搜到了 { //cout<<judge<<endl; int sum2=0; for(int j=0;j<judge;j++) { int tt=int(ts[j])-48; sum2=sum2*10+tt; } s[numble].time=s[numble].time+sum2; int judge2=ts.find(")"); s[numble].timu++; int sum=0; for(int j=judge+1;j<judge2;j++) { int tt=int(ts[j])-48; sum=sum*10+tt; } s[numble].time=s[numble].time+sum*b;//f罚时 } } numble++; } for(int i=0;i<numble-1;i++) for(int j=0;j<numble-1-i;j++) { if(s[j].zidianxu>s[j+1].zidianxu) { student ttem=s[j]; s[j]=s[j+1]; s[j+1]=ttem; } } for(int i=0;i<numble-1;i++) for(int j=0;j<numble-1-i;j++) { if(s[j].time>s[j+1].time) { student ttem=s[j]; s[j]=s[j+1]; s[j+1]=ttem; } } for(int i=0;i<numble-1;i++) for(int j=0;j<numble-1-i;j++) { if(s[j].timu<s[j+1].timu) { student ttem=s[j]; s[j]=s[j+1]; s[j+1]=ttem; } } for(int i=0;i<numble;i++) { printf("%-10s ",s[i].name.c_str()); /* for(int j=0;j<10-s[i].name.length();j++) cout<<" ";*/ printf("%2d ",s[i].timu); printf("%4d",s[i].time); cout<<endl; } return 0;
题目三:瑞神打牌
题目描述
瑞神HRZ因为疫情在家闲得无聊,同时他又非常厉害,所有的课对他来说都是水一水就能拿A+,所以他无聊,找来了另外三个人:咕咕东,腾神以及zjm来打牌(天下苦瑞神久矣)。
显然,牌局由四个人构成,围成一圈。我们称四个方向为北 东 南 西。对应的英文是North,East,South,West。游戏一共由一副扑克,也就是52张构成。开始,我们指定一位发牌员(东南西北中的一个,用英文首字母标识)开始发牌,发牌顺序为顺时针,发牌员第一个不发自己,而是发他的下一个人(顺时针的下一个人)。这样,每个人都会拿到13张牌。
现在我们定义牌的顺序,首先,花色是(梅花)<(方片)<(黑桃)<(红桃),(输入时,我们用C,D,S,H分别表示梅花,方片,黑桃,红桃,即其单词首字母)。对于牌面的值,我们规定2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A。
现在你作为上帝,你要从小到大排序每个人手中的牌,并按照给定格式输出。(具体格式见输出描述和样例输出)。
Input
输入包含多组数据
每组数据的第一行包含一个大写字符,表示发牌员是谁。如果该字符为‘#’则表示输入结束。
接下来有两行,每行有52个字符,表示了26张牌,两行加起来一共52张牌。每张牌都由两个字符组成,第一个字符表示花色,第二个字符表示数值。
Output
输出多组数据发牌的结果,每组数据之后需要额外多输出一个空行!!!!!
每组数据应该由24行的组成,输出按照顺时针方向,始终先输出South Player的结果,每位玩家先输出一行即玩家名称(东南西北),接下来五行,第一行和第五行输出固定格式(见样例),第二行和第四行按顺序和格式输出数值(见样例),第三行按顺序和格式输出花色(见样例)。
Sample Input
N CTCAH8CJD4C6D9SQC7S5HAD2HJH9CKD3H6D6D7H3HQH4C5DKHKS9 SJDTS3S7S4C4CQHTSAH2D8DJSTSKS2H5D5DQDAH7C9S8C8S6C2C3 #
Sample Output
South player: +---+---+---+---+---+---+---+---+---+---+---+---+---+ |6 6|A A|6 6|J J|5 5|6 6|7 7|9 9|4 4|5 5|7 7|9 9|T T| | C | C | D | D | S | S | S | S | H | H | H | H | H | |6 6|A A|6 6|J J|5 5|6 6|7 7|9 9|4 4|5 5|7 7|9 9|T T| +---+---+---+---+---+---+---+---+---+---+---+---+---+ West player: +---+---+---+---+---+---+---+---+---+---+---+---+---+ |2 2|5 5|9 9|K K|5 5|7 7|9 9|4 4|T T|J J|A A|8 8|A A| | C | C | C | C | D | D | D | S | S | S | S | H | H | |2 2|5 5|9 9|K K|5 5|7 7|9 9|4 4|T T|J J|A A|8 8|A A| +---+---+---+---+---+---+---+---+---+---+---+---+---+ North player: +---+---+---+---+---+---+---+---+---+---+---+---+---+ |3 3|4 4|J J|2 2|3 3|T T|Q Q|K K|8 8|Q Q|K K|2 2|3 3| | C | C | C | D | D | D | D | D | S | S | S | H | H | |3 3|4 4|J J|2 2|3 3|T T|Q Q|K K|8 8|Q Q|K K|2 2|3 3| +---+---+---+---+---+---+---+---+---+---+---+---+---+ East player: +---+---+---+---+---+---+---+---+---+---+---+---+---+ |7 7|8 8|T T|Q Q|4 4|8 8|A A|2 2|3 3|6 6|J J|Q Q|K K| | C | C | C | C | D | D | D | S | S | H | H | H | H | |7 7|8 8|T T|Q Q|4 4|8 8|A A|2 2|3 3|6 6|J J|Q Q|K K| +---+---+---+---+---+---+---+---+---+---+---+---+---+
题意解析
事实上我觉得这个题与第二题并没什么什么本质的区别:如何读入数据并把它们处理成一种比较规整的形式。同时经过简单排序后再用一种规整的形式输出。
做法
逐步分解这个问题。
首先牌有花色、数值两个属性,但为了方便比较,我令梅花的“数值”为100,方片为200以此类推把花色“换算”成数字相加后方便比较大小。同时将AJQK转化为方便比较的数字。这个过程可以用map来完成。
把牌作为结构体,令其具有花色、数值、数字三个属性(数字用于排序)。同时玩家有四名,所以可以声明一个s[4][13]的数组来存储四个玩家的手牌。
发牌过程可以利用对4取余来实现逆时针发牌。
在读入结束后,根据数字对玩家的手牌进行排序,然后按照要求输出即可。
代码
#include <iostream> #include <map> #include <algorithm> using namespace std; /*现在我们定义牌的顺序, 首先,花色是(梅花)<(方片)<(黑桃)<(红桃), (输入时,我们用C,D,S,H分别表示梅花,方片,黑桃,红桃,即其单词首字母)。 对于牌面的值,我们规定2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A。 */ /* run this program using the console pauser or add your own getch, system("pause") or input loop */ map<char,int> pai; map<char,int> tc; struct card{ char huase; char shuzi; int numble; card() { huase=' '; shuzi=' ';numble=0; } void p1() { cout<<"|"<<shuzi<<" "<<shuzi; } void p2() { cout<<"|"<<" "<<huase<<" "; } }; bool bijiao(card a,card b) { return a.numble<b.numble; } card s[4][13];//0 1 2 3分别为 南 西 北 东 int main(int argc, char** argv) { pai['C']=100; pai['D']=200; pai['S']=300; pai['H']=400; pai['2']=1; pai['3']=2; pai['4']=3; pai['5']=4; pai['6']=5; pai['7']=6; pai['8']=7; pai['9']=8; pai['T']=9; pai['J']=10; pai['Q']=11; pai['K']=12; pai['A']=13; tc['S']=0; tc['W']=1; tc['N']=2; tc['E']=3; string d[4]={"South player:","West player:","North player:","East player:"}; char head; while(cin>>head) { if(head=='#') break; int numble=tc[head]+1; int shu=0;//记录每个牌手手里的牌数 for(int i=0;i<52;i++) { char a,b; cin>>a>>b; int tem=pai[a]+pai[b];//排序大小 s[numble%4][shu].huase=a; s[numble%4][shu].shuzi=b; s[numble%4][shu].numble=tem; numble++; if((i+1)%4==0) { shu++; } } for(int i=0;i<4;i++) sort(s[i],s[i]+13,bijiao); for(int i=0;i<4;i++) { cout<<d[i]<<endl; cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl; for(int j=0;j<13;j++) { s[i][j].p1(); } cout<<"|"<<endl; for(int j=0;j<13;j++) { s[i][j].p2(); } cout<<"|"<<endl; for(int j=0;j<13;j++) { s[i][j].p1(); } cout<<"|"<<endl; cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl; } cout<<endl; } return 0; }
- 点赞
- 收藏
- 分享
- 文章举报
- 程序设计思维与实践 Week2 作业+实验
- week2 实验B - 爆零(×)大力出奇迹(√)
- 我的作业之旅之程序设计思维与实践 Week2 作业和实验题(共五道)
- 程序设计Week2实验——C-瑞神打牌
- 程序设计思维与实践 Week2 实验:C - 瑞神打牌 (不支持C++11;G++和C++编译器都试试!)
- 程序设计思维与实践 Week2 实验 C - 瑞神打牌
- week2 实验C - 瑞神打牌
- 20135202闫佳歆--week 8 实验:理解进程调度时机跟踪分析进程调度与进程切换的过程--实验及总结
- 实验week2 C-瑞神打牌
- 程序设计Week2实验——B - 爆零(×)大力出奇迹(√)
- 程序设计思维与实践 Week2 实验:B - 爆零(×)大力出奇迹(√)
- 程序设计思维与实践 Week2 实验 B - 爆零(×)大力出奇迹(√)
- 实验week2 B - 爆零(×)大力出奇迹(√)
- 程序设计Week2实验——A-化学
- 20135202闫佳歆--week3 跟踪分析Linux内核的启动过程--实验及总结
- 程序设计思维与实践 Week2实验 C - 瑞神打牌
- WEEK2 实验C - 瑞神打牌
- week2实验——C题
- 程序设计思维与实践 Week2 实验
- WEEK2 实验B 爆零(×)大力出奇迹(√)