程序设计WEEK2实验

一、A - 化学

1.题目

化学很神奇,以下是烷烃基。
在这里插入图片描述
假设如上图,这个烷烃基有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.解题思路

(1)观察烷烃基的区别(图中类别由左到右编号1 2 3 4 5),发现编号1各点的度数由小到大为1 1 2 2 2,编号4度数由小到大为1 1 1 2 2 3,可知由度数排序可区分编号1 4 5。而当输入一个烷烃基时,输入的点相同编号的个数即为改点的度数,可定义数组存储该烷烃基的各点度数,sort排序后区分类别1 4 5。

(2)类别编号2 3可用link二维数组记录点与点的连接情况,类别编号3中,度数为3的点连接两个度数为2 的点,而类别编号2则不然。故可以找到度数为3的点,判断是否与度数为2 的点全部连接区分类别2 3。

3.c++代码

#include<iostream>
#include<map>
#include<algorithm>
#include<math.h>
#include<string>
#include<cstring>
#include<iomanip>
using namespace std;

//map<int,int> thisMap;

 int main()
 {
 	int n;
	cin>>n;
	int x,y,two1=0,two2=0,three=0;
	int a[6]={0,0,0,0,0,0};
	int b[6]={0,0,0,0,0,0};
	bool link[6][6];//表示节点之间是否项相连 
	for(int i=0;i<n;i++)
	{	
		for(int j=0;j<6;j++)
		{
			a[j]=0;
			b[j]=0;
			for(int j1=0;j1<6;j1++)
				link[j][j1]=0;//不相连 
		}
		for(int i1=0;i1<5;i1++)
		{
			cin>>x>>y;
			a[x-1]++;
			a[y-1]++;
			b[x-1]++;
			b[y-1]++;
			link[x-1][y-1]=1;
			link[y-1][x-1]=1;
			//cout<<'a'<<x-1<<' '<<y-1<<' '<<link[x-1][y-1]<<' '<<endl;
		}
		sort(a,a+6);
		//for(int i=0;i<6;i++)
		//cout<<a[i]<<endl;
		if(a[0]==1&&a[1]==1&&a[2]==2&&a[3]==2&&a[4]==2&&a[5]==2)
			cout<<"n-hexane"<<endl;
		else if(a[0]==1&&a[1]==1&&a[2]==1&&a[3]==1&&a[4]==3&&a[5]==3)
			cout<<"2,3-dimethylbutane"<<endl;
		else if(a[0]==1&&a[1]==1&&a[2]==1&&a[3]==1&&a[4]==2&&a[5]==4)
			cout<<"2,2-dimethylbutane"<<endl;
		else if(a[0]=1&&a[1]==1&&a[2]==1&&a[3]==2&&a[4]==2&&a[5]==3)
		{
			for(int p=0;p<6;p++)
			{
				if(b[p]==2)
				{
					two2=two1;
					two1=p;
				}
			}
			if(link[two1][two2])
				cout<<"2-methylpentane"<<endl;
			else cout<<"3-methylpentane"<<endl;
		}
	}
	return 0;
 }

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

1.题目

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

2.解题思路

(1)结构体student保存该学生的姓名、已通过的题目数、总罚时。

(2)对单独一个学生,进行题号的循环,循环内用char数组保存该题的作答情况。对char[0]的各情况进行讨论。若其为‘-’(未作出该题)、‘0’(未做该题)则continue进行下一个循环。否则就是已作出该题(没有罚时/有罚时)。循环遍历该char数组,在’('之前,ans=ans*18+s[i]-‘0’,否则就算出括号中的数字与ans相加,得出总罚时。注意如果没有发生continue就意味着该题做出,num++。

(3)格式控制输出时,循环中加入cout.unsetf(ios::right);,否则会一直右对齐输出。

3.c++代码

#include<iostream>
#include<map>
#include<algorithm>
#include<math.h>
#include<string>
#include<cstring>
#include<iomanip>
using namespace std;

//map<int,int> thisMap;
const int MAX=10000;
struct student
{
	char name[10];
	int num;
	int time;
}stu[MAX];//MAX必须const 

bool cmp(student s1,student s2)
{
	if(s1.num!=s2.num)
	return s1.num>s2.num;
	else if(s1.time!=s2.time)
	return s1.time<s2.time;
	else return strcmp(s1.name,s2.name)<0;
}
int main()
{
	int n,m;
	cin>>n>>m;
	int k=0,temp=0,temp1=0,count=0;
	while(cin>>stu[k].name)
	{
		//cout<<'n'<<stu[k].name<<endl;
		char s[10];
		stu[k].num=0;
		stu[k].time=0;
		count=0;
		for(int i=0;i<n;i++)
		{
			
			cin>>s;
			if(s[0]=='-')
				continue;
			if(s[0]=='0')
				continue;
			//剩下的都是正数
			stu[k].num++;
			temp1=0;
			for(int i=0;i<strlen(s);i++)
			{
				count++;
				temp=0;
				if(s[i]=='(')
				{
					for(int j=i+1;s[j]!=')';j++)
					{
						temp=temp*10+s[j]-'0';
						//temp=temp+m*(s[j]-'0');
					}
					stu[k].time+=m*temp;
					break;
				}
				temp1=temp1*10+s[i]-'0';
				//cout<<'p'<<temp1;
			}
			stu[k].time+=temp1;
			//cout<<'t'<<stu[k].time<<endl;
				
		}
		if(count=0)stu[k].time=0;
		k++;
	}
	
	sort(stu,stu+k,cmp);
	//cout<<"<<<<<<<<"<<endl;
	for(int i=0;i<k;i++)
	{
		cout<<setiosflags(ios::left);
		cout<<setw(10)<<stu[i].name<<' ';
		cout<<setiosflags(ios::right);
		cout<<setw(2)<<stu[i].num<<' ';
		cout<<setw(4)<<stu[i].time<<endl;
		cout.unsetf(ios::right);
		
	}
	return 0;
 } 

三、C - 瑞神打牌 (不支持C++11;G++和C++编译器都试试!)

1.题目

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

2.解题思路

(1)结构体poker表示每张牌,含有花色和卡片数字,都用char表示。用map将每个方向(S/W/N/E)与0 1 2 3绑定;将卡片数字1A与114绑定;将花色(C/D/S/H)与1 2 3 4绑定。定义二维数组a,a[0]为S方向获得的牌,a[1]为W,a[2]为N,a[3]为E。

(2)对于每组数据的卡片值输入,循环遍历52次,每次接受一个卡片的输入,将其存储在原方向顺时针的下一个人的牌面数组a中,即数组下标为d=(d+1)%4;,当每循环四次,二维索引t+1。

(3)输出时,定义string数组,存储"South player",“West player”,“North player”,“East player”。循环4次,按顺序将a数组中的卡片输出。

3.c++代码

#include<iostream>
#include<map>
#include<algorithm>
#include<math.h>
#include<string>
#include<cstring>
using namespace std;

//每个人绑定一个数组存储牌面(二维数组实现),sort排序 
struct poker
{
	char color;
	char num;
};

map<char,int> map1;
map<char,int> map2;
map<char,int> map3;
poker a[4][13];//每人13张牌

bool cmp(poker p1,poker p2)
{
	if(p1.color!=p2.color)
		return map3[p1.color]<map3[p2.color];
	else return map2[p1.num]<map2[p2.num];
}

int main()
{
	map1['S']=0;map1['W']=1;map1['N']=2;map1['E']=3;
	map2['1']=1;map2['2']=2;map2['3']=3;map2['4']=4;map2['5']=5;
	map2['6']=6;map2['7']=7;map2['8']=8;map2['9']=9;
	map2['T']=10;map2['J']=11;map2['Q']=12;map2['K']=13;map2['A']=14;
	map3['C']=1;map3['D']=2;map3['S']=3;map3['H']=4;
	
	string player[4]={"South player","West player","North player","East player"};
	char dir,c,b;
	int t=0;
	while(cin>>dir&&dir!='#')
	{
		t=0;
		int d=map1[dir];
		for(int i=0;i<52;i++)
		{
			poker thisPoker;
			cin>>c>>b;
			thisPoker.color=c;thisPoker.num=b;
			d=(d+1)%4;
			a[d][t]=thisPoker;
			if(i!=0&&i%4==3)t++;
		}
		
		//输出
		for(int i=0;i<4;i++)
			sort(a[i],a[i]+13,cmp);
		for(int i=0;i<4;i++)
		{
			cout<<player[i]<<':'<<endl;
			cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
			for(int j=0;j<13;j++)
				cout<<'|'<<a[i][j].num<<' '<<a[i][j].num;
			cout<<'|'<<endl;
			for(int j=0;j<13;j++)
				cout<<'|'<<' '<<a[i][j].color<<' ';
			cout<<'|'<<endl;
			for(int j=0;j<13;j++)
				cout<<'|'<<a[i][j].num<<' '<<a[i][j].num;
			cout<<'|'<<endl;
			cout<<"+---+---+---+---+---+---+---+---+---+---+---+---+---+"<<endl;
		}
		cout<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值