Week2 实验

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

Example Output

n-hexane
3-methylpentane

题意:
通过所给数据构造出一种烷烃,并根据这一种烷烃的特点输出其名称。

分析:
这道题给出了五种不同的烷烃,通过观察可以发现,每个原子的度不一样,最大度为2的一定为n-hexane,最大度为4的一定是2,2-dimethylbutane,有两个元素度为3的一定是2,3-dimethylbutane,值得注意的是2-methylpentane和3-methylpentane的六个原子度都一样,但2-methylpentane度为3的原子上连接着两个度为1的原子,3-methylpentane度为3的原子上连接着两个度为2的原子,通过这一点可以将其区分,在输入数据后,统计每个数字出现的次数,就可以得到每一个原子的度,最后还要注意输出时单词的拼写一定要正确。

代码如下:

#include<iostream>
#include<algorithm>
using namespace std;

int main()
{
	int T;
	int a,b;
	cin>>T;
	while(T--)
	{
		bool label=true;
		int value[7]={0};//点 
		int judge[7][7]={0};//边 
		for(int i=0;i<5;i++)
		{
			cin>>a>>b;
			value[a]++;
			value[b]++;
			judge[a][b]=1;
			judge[b][a]=1;
		}
		int m=0,x=0,y=0;
		for(int i=1;i<7;i++)
		{
			if(value[i]==3)
				m=i;//度为3的原子 
			else if(value[i]==2)
			{
				if(x==0&&y==0)
					x=i;//度为2的原子 
				else
					y=i;//另外一个度为2的原子 
			}
		}
		if(judge[m][x]!=1||judge[x][m]!=1||judge[m][y]!=1||judge[y][m]!=1)
			label=false;
		sort(value,value+7);
		if(value[6]==2)
			cout<<"n-hexane"<<endl;
		else if(value[6]==4)
			cout<<"2,2-dimethylbutane"<<endl;
		else if(value[5]==3&&value[6]==3)
			cout<<"2,3-dimethylbutane"<<endl;
		else
		{
			if(label)
				cout<<"3-methylpentane"<<endl;
			else
				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个字符宽,右对齐)。名字、题数和时间分相互之间有一个空格。数据保证可按要求的输出格式进行输出。

Example 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

Example Output

在这里插入图片描述

题意:
将所给的一列数据换算成题目数量和时间,并根据要求进行多关键字排序。

分析:
这道题从根本上来说是一道多关键字排序的问题,应当使用自定义排序函数来解决,并且排序的规则很简单,排序函数很容易写出来,但困难的地方在于对于输入数据的接受处理和输出的格式,刚开始我通过if语句去判断括号的存在,不仅麻烦而且特别容易出错,后来查了一些资料,最后觉得使用sscanf函数可以很好地解决问题,sscanf函数直接提取出括号内外的值,对计算时间有很大帮助,这道题在测试过程中应当手动输入Ctrl+Z来得到结果。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
#include<string.h>
using namespace std;

struct student
{//结构体 
	char name[10];
	int number = 0;
	int time = 0;
}stu[1000];

int cmp(student a, student b)
{//自定义排序函数 
	return((a.number > b.number) || (a.number == b.number && a.time < b.time)
		|| (a.number == b.number && a.time == b.time && strcmp(a.name, b.name) < 0));
}

int main()
{
	int n, m;
	cin >> n >> m;
	char back[10];
	int i = -1;
	while (scanf("%s", &stu[++i].name) != EOF)
	{
		int x, y;
		for (int j = 0; j < n; j++)
		{
			cin >> back;
			//sscanf函数的应用使代码变得简单 
			int a = sscanf(back, "%d(%d)", &x, &y);
			if (a == 1)
			{
				if (x > 0)
				{
					stu[i].number++;
					stu[i].time += x;
				}
			}
			else if (a == 2)
			{
				stu[i].number++;
				stu[i].time += x + y * m;
			}
		}
	}
	sort(stu, stu + i, cmp);
	for (int j = 0; j < i; j++)
	{//注意输出右对齐格式 
		printf("%-10s %2d %4d\n", stu[j].name, stu[j].number, stu[j].time);
	}
	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的结果,每位玩家先输出一行即玩家名称(东南西北),接下来五行,第一行和第五行输出固定格式(见样例),第二行和第四行按顺序和格式输出数值(见样例),第三行按顺序和格式输出花色(见样例)。

Example Input

在这里插入图片描述

Example Output

在这里插入图片描述

题意:
接受两列字符串,将这些字符串转化为纸牌的花色和号码,并按一定规则分发给四个人,并对每个人手中的纸牌按照规则进行多关键字排序。

分析:
这道题可以定义一个结构体,两个量分别表示花色和号码,还需要编写函数将这两个量转化为数字,进一步编写自定义排序函数,用来给扑克排序,一共四位玩家,所以发牌的顺序很重要,注意是从发牌员的下一个人开始发牌并且顺时针旋转,所以只需要注意数组的下标一一对应,在输出过程中,注意输出格式,否则很容易出错。

代码如下:

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

char HS[4] = { 'C','D','S','H' };
char HM[13] = { '2','3','4','5','6','7','8','9','T','J','Q','K','A' };

struct zp
{//结构体 
	char hs;
	char hm;
} poke[4][13];//4个人每人13张牌 

int px_HS(char a)
{
	for (int i = 0; i < 4; i++)
		if (HS[i] == a)
			return i+1;
	return -1;
}

int px_HM(char a)
{
	for (int i = 0; i < 13; i++)
		if (HM[i] == a)
			return i+1;
	return -1;
}

int cmp(zp a, zp b)
{//自定义排序函数 
	int hsa, hsb, hma, hmb;
	hsa = px_HS(a.hs);
	hsb = px_HS(b.hs);
	hma = px_HM(a.hm);
	hmb = px_HM(b.hm);
	return ((hsa < hsb) || ((hsa == hsb) && hma < hmb));
}

int main()
{
	char n;
	int m;
	while (cin >> n)
	{
		if (n == '#')
			break;
		else if (n == 'N')//从下一个人开始发牌 
			m = 3;
		else if (n == 'E')
			m = 0;
		else if (n == 'S')
			m = 1;
		else if (n == 'W')
			m = 2;
		for (int i = 0; i < 52; i++)
		{
			char a, b;
			cin >> a >> b;
			poke[m][i / 4].hs = a;
			poke[m][i / 4].hm = b;
			m = (m + 1) % 4;
		}
		for (int i = 0; i < 4; i++)
		{//排序 
			sort(poke[i], poke[i] + 13, cmp);
		}
		for (int i = 0; i < 4; i++)
		{
			if (i == 0)
				cout << "South player:" << endl;
			else if (i == 1)
				cout << "West player:" << endl;
			else if (i == 2)
				cout << "North player:" << endl;
			else if (i == 3)
				cout << "East player:" << endl;
			cout << "+---+---+---+---+---+---+---+---+---+---+---+---+---+" << endl;
			for (int j = 0; j < 13; j++)
				cout << "|" << poke[i][j].hm << " " << poke[i][j].hm;
			cout << "|" << endl;
			for (int j = 0; j < 13; j++)
				cout << "|" << " " << poke[i][j].hs << " ";
			cout << "|" << endl;
			for (int j = 0; j < 13; j++)
				cout << "|" << poke[i][j].hm << " " << poke[i][j].hm;
			cout << "|" << endl;
			cout << "+---+---+---+---+---+---+---+---+---+---+---+---+---+" << endl;
		}
		cout << endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值