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;
}
上一篇: 自动化定位元素策略分析
下一篇: Revit二开--判断元素是否被标记过