【Week2 实验】A - 化学、B - 爆零(×)大力出奇迹(√)、C - 瑞神打牌

A - 化学

题目:

化学很神奇,以下是烷烃基。
在这里插入图片描述
假设如上图,这个烷烃基有6个原子和5个化学键,6个原子分别标号1~6,然后用一对数字 a,b 表示原子a和原子b间有一个化学键。这样通过5行a,b可以描述一个烷烃基。
你的任务是甄别烷烃基的类别。
原子没有编号方法,比如
1 2
2 3
3 4
4 5
5 6

1 3
2 3
2 4
4 5
5 6
是同一种,本质上就是一条链,编号其实是没有关系的,可以在纸上画画就懂了。

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

思路做法:

认真比较每个烷烃基,寻找判别的方法。
可以发现:这些烷烃基中,1种是每个碳原子最多与2个碳原子相连,1种是每个碳原子最多与4个碳原子相连的,另外3种每个碳原子最多与3个碳原子相连,但其中1种与3个碳原子相连的碳原子个数为2,1种相连的3个碳原子中有2个要与2个碳原子相连,1种相连的3个碳原子中只有1个要与2个碳原子相连。
统计这种数值,就可以分类出来。

总结:

不是很难的一道模拟题,甚至有人出错在将名称输错。注意每种烷烃基的判别条件就行。

代码:

#include <iostream>
#include <string.h>
using namespace std;
int JW[7][5];
int main(){
	int t;
	cin>>t;
	while(t--){
		memset(JW,0,sizeof(JW));
		int a,b,c3=0,c4=0,pos=0;
		for(int i=0;i<5;i++){
			cin>>a>>b;
			JW[a][++JW[a][0]]=b;
			JW[b][++JW[b][0]]=a;
		}
		for(int i=1;i<7;i++){
			if(JW[i][0]==3){
				c3++;
				pos=i;
			}
			if(JW[i][0]==4) c4++;
		}
		if(!c3&&!c4) cout<<"n-hexane"<<endl;
		else if(!c4&&c3==2) cout<<"2,3-dimethylbutane"<<endl;
		else if(c4) cout<<"2,2-dimethylbutane"<<endl;
		else{
			int cnt=0;
			for(int i=1;i<=JW[pos][0];i++){
				if(JW[JW[pos][i]][0]==2) cnt++;
			}
			if(cnt==2) cout<<"3-methylpentane"<<endl;
			else if(cnt==1) cout<<"2-methylpentane"<<endl;
		}
	}
	return 0;
} 

B - 爆零(×)大力出奇迹(√)

题目:

程序设计思维作业和实验使用的实时评测系统,具有及时获得成绩排名的特点,那它的功能是怎么实现的呢?
我们千辛万苦怼完了不忍直视的程序并提交以后,评测系统要么返回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

思路做法:

题目未提及数据量大小,因此定义一个较大的量开辟数组即可。
定义一个get_score函数(其实是为了获取时间get_time,只是名字略有不同但并无碍),该函数将字符串转化为耗时,为处理多种输入,用if判断:若首位为‘0’或‘-’,直接返回0即可(无时间分,同时不算入AC次数),否则更新用时和出错次数(初始都为0),最后返回与此字符串对应的时间分。
创建student类并根据题意重载小于号,用stl的sort排序,按相应格式输出即可。

总结:

个人认为考验的主要是输入字符串的转化和sort排序,这2个地方处理好后结果应该无大碍了,最后还有一个输出的格式化要注意,cout、printf都有相应的方式。

代码:

#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>
using namespace std;
const int N=5000;
int n,m;
struct student{
	string name;
	int ac;
	int time;
	student(){}
	student(string _name,int _ac,int _time):name(_name),ac(_ac),time(_time){}
	bool operator<(const student& temp){
		if(ac!=temp.ac) return ac>temp.ac;
		if(time!=temp.time) return time<temp.time;
		return name<temp.name;
	}
};
student a[N];
int get_score(string score){
	int n=score.size(),flag=0,num=0,fail=0;
	for(int i=0;i<n;i++){
		if(n==1&&score[i]==0) return 0;
		if(i==0&&score[i]=='-') return 0;
		if(score[i]=='('||score[i]==')'){
			flag=1;
			continue;
		}
		if(!flag) num=num*10+score[i]-'0';
		else fail=fail*10+score[i]-'0';
	}
	return num+fail*m;
}
int main(){
	cin>>n>>m;
	int num=0;
	string name,score;
	while(cin>>name){
		int all_time=0,time,ac=0;
		for(int i=0;i<n;i++){
			cin>>score;
			time=get_score(score);
			if(time>0){
				all_time+=time;
				ac++;
			}
		}
		a[num++]=student(name,ac,all_time);
	}
	sort(a,a+num);
	for(int i=0;i<num;i++){
		cout<<setw(10)<<left<<a[i].name<<" ";
		cout<<setw(2)<<right<<a[i].ac<<" ";
		cout<<setw(4)<<right<<a[i].time<<endl;
	}
	return 0;
} 

C - 瑞神打牌

题目:

瑞神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|
+---+---+---+---+---+---+---+---+---+---+---+---+---+

思路做法:

用结构体pai来表示牌,并重载小于号用于之后的牌堆排序。这里的排序方案是比较字符,可以用map来建立一个映射,可以理解为花色(或牌面值)的大小,重载小于号要比较花色(或牌面值)大小时相当于比较其映射后的数字大小。
将输入接收到二维结构体数组中,再分行排序,最后计算发现South player始终对应于二维数组player中的某行固定不变(无论发牌员是谁,因为初始有一个映射mp标志打牌的人的固定坐标),因此最后按顺序输出相应格式的结果(代码中始终从2开始)。

总结:

输入时小心用吞掉回车,导致后面的输出全部错误。
重点仍然在于排序,代码中对于二维结构体数组中的每行(即每个player的牌)排序是先将每行数据复制到一个一维结构体数组the_player中再用sort,另一种是直接取每行首元素和尾元素的地址进行排序(sort(&,&))。排好序按要求的格式输出,小心多输或少输换行导致的错误。

代码:

#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
char players[]={'N','E','S','W'};
string s[]={"North player:","East player:","South player:","West player:"};
string sign="+---+---+---+---+---+---+---+---+---+---+---+---+---+";
char colors[]={'C','D','S','H'};
char nums[]={'2','3','4','5','6','7','8','9','T','J','Q','K','A'};
map<char,int> mp;
map<char,int> the_color;
map<char,int> the_num;
struct pai{
	char color;
	char num;
	pai(){}
	pai(char _color,char _num):color(_color),num(_num){}
	bool operator<(const pai& p)const{
		if(color!=p.color) return the_color[color]<the_color[p.color];
		return the_num[num]<the_num[p.num];
	}
};
pai player[4][13];
pai the_player[13];
int main(){
	char starter;
	string kapai,kapai1,kapai2;
	for(int i=0;i<4;i++) mp[players[i]]=i;
	for(int i=0;i<4;i++) the_color[colors[i]]=i;
	for(int i=0;i<13;i++) the_num[nums[i]]=i;
	while(cin>>starter){
		if(starter=='#') break;
		int nowplayer=(mp[starter]+1);
		cin>>kapai1>>kapai2;
		kapai=kapai1+kapai2;
		char color,num;
		int cnt=0;
		for(int i=0;i<13;i++){
			for(int j=0;j<4;j++){
				color=kapai[cnt++];
				num=kapai[cnt++];
				player[(nowplayer+j)%4][i]=pai(color,num);
			}
		}
		for(int i=2;i<6;i++){
			int n=i%4;
			for(int j=0;j<13;j++){
				the_player[j]=player[n][j];
			}
			sort(the_player,the_player+13);
			cout<<s[n]<<endl;
			cout<<sign<<endl;
			for(int j=0;j<13;j++){
				cout<<"|"<<the_player[j].num<<" "<<the_player[j].num;
			}cout<<"|"<<endl;
			for(int j=0;j<13;j++){
				cout<<"| "<<the_player[j].color<<" ";
			}cout<<"|"<<endl;
			for(int j=0;j<13;j++){
				cout<<"|"<<the_player[j].num<<" "<<the_player[j].num;
			}cout<<"|"<<endl;
			cout<<sign<<endl;
		}
		cout<<endl;
	}
	return 0;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

容嬷嬷当年一枝花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值