week2实验

A - 化学 (编译器选 GNU G++)
化学很神奇,以下是烷烃基。
在这里插入图片描述

假设如上图,这个烷烃基有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

题目分析:
本题目主要是对于认知方面上的考察,题目中烷烃中的碳原子是没有标号的,所以我们要把握住其中的本质,其结构是不会因原子标号的不同而改变的,也就是说我们要解决这个问题,就要从结构本质出发,而结构的决定是由每一个碳原子的出入度所决定的,所以我们要在碳原子的出入度上寻找不同,从而获取判定条件。对于上面五种烷烃,我们会发现n-hexane中度数为2的原子数为4个,2,2-dimethylbutane中度数为2的点的原子个数为1个,2,3-dimethylbutane中度数为2的原子数为0个,而对于3-methylpentane和2-methylpentane两种结构中度数为2的原子个数都为2个,这样我们就针对于度数为三的原子进行考虑,如果与度数为三的碳原子相邻的碳原子中度数为1的个数为1个,则为3-methylpentane,否则为2-methylpentane,在本题中我们利用结构体数组no保留原始输入信息,利用数组a保留每个点的度数,利用数组b保留度数为i的点的个数,总的来讲,这道题考察了认知能力,寻找定量与静量,以静制动,另外重点是对于数组的使用。

代码实现:

#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
using namespace std;
struct node {
	int a,b;
	node() {

	}
	node(int _a,int _b) {
		a=_a;
		b=_b;
	}
};
int a[7]={0};
int b[7]={0};
int main()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		node* no=new node[5];
		int x,y;
		for(int j=0;j<5;j++)
		{
			cin>>x>>y;
			no[j].a=x;
			no[j].b=y;
		}
		for(int j=0;j<5;j++)
		{
			a[no[j].a]++;
			a[no[j].b]++;
		}
		for(int j=1;j<7;j++)
		{
			b[a[j]]++;
		}
		if(b[2]==4)
		cout<<"n-hexane"<<endl;
		if(b[2]==1)
		cout<<"2,2-dimethylbutane"<<endl;
		if(b[2]==0)
		cout<<"2,3-dimethylbutane"<<endl;
		if(b[2]==2)
		{
			int func=0;
			for(int j=1;j<7;j++)
			{
				if(a[j]==3)
				func=j;
			}
			int func2=0;
			for(int i=0;i<5;i++)
			{
				if(no[i].a==func)
				{
					if(a[no[i].b]==1)
					{
						func2++;
					}
				}
				if(no[i].b==func)
				{
					if(a[no[i].a]==1)
					{
						func2++;
					}
				}
			}
			if(func2==1)
			cout<<"3-methylpentane"<<endl;
			else
			cout<<"2-methylpentane"<<endl;
		}		
		delete[] no;
	}
}在这里插入代码片

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

题目分析:
这道题的核心是对于编程语言的一些基本输入输出的考察,重点在于对字符串的处理,以及标准化的输入输出问题。对于本题,我们是利用一个结构体存储每一位同学的信息的,这样我们对符号进行重载,使得排序要求被解决。对于字符串的读入,这里的代码利用的是string进行处理的,过程相对较为复杂,如若是利用char型数组,我们可以利用sscanf(char*,"%d(%d)",&x,&y)进行读入,利用其返回值获取读入数的个数,这样就避免了从字符串中再次解析数字的过程,也就大大简化了程序。

#include<iostream>
#include<string>
#include<vector>
#include<algorithm> 
#include<cmath>
#include<sstream> 
using namespace std;
int funcc = 0;
int n, m;//n为题目数量;m为罚时;
int change(string& a) {
	int sum = 0;
	int size = a.size();
	if (a[0] == '-' || a[0] == '0')
		return 0;
	if (a[size - 1] != ')') {
		funcc++;
		for (int i = size - 1; i >= 0; i--) {
			sum = sum + (a[i]-'0') * pow(10, size - 1 - i);
		}
		return sum;
	}
	else {
		funcc++;
		int num = 0;
		for (int i = size - 1; a[i] != '('; i--) {
			num++;
		}
		for (int i = size - num - 2; i >= 0; i--) {
			sum = sum + (a[i]-'0') * pow(10, size - num - 2 - i);
		}
		int num1 = 0;
		for (int i = size - 2; i >= size - num; i--) {
			num1 = num1 + (a[i]-'0') * pow(10, size - i - 2);
		}
		return sum + num1 * m;
	}
}
struct node {
	string name;
	string* score;
	int su;//表示对的题目数量; 
	node() {
		score = new string[n];
	}
	int func() const{
		int sum = 0;
		for (int i = 0; i < n; i++) {
			sum = sum + change(score[i]);
		}
		return sum;
	}
	 bool operator>(const node& p)const {
		if (su != p.su)
			return su > p.su;
		else if (su == p.su && this->func() != p.func())
		{
			return this->func()<p.func();
		}
		else
		{
			return this->name<p.name;
		}
	}
};

int main() {
	cin >> n >> m;
	string s;
	vector<node> no;
	int j=0;
	while(cin>>s)
	{
		funcc=0;
		node cc;
		cc.name=s;
		for(int i=0;i<n;i++)
		{
			cin>>s;
			cc.score[i]=s;
			change(s);
		}
		cc.su=funcc;
		no.push_back(cc);
	}
	int num = no.size();
	sort(no.begin(), no.end(), greater<node>());
	for(int i=0;i<num;i++)
	{
		printf("%-10s %2d %4d\n",no[i].name.c_str(),no[i].su,no[i].func());
	}
}在这里插入代码片

C - 瑞神打牌 (不支持C++11;G++和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:在这里插入图片描述

题目思路解析:
这道题目本身并不是很难,主要涉及到字符串的读入问题,对于本题,我们为表示一张牌构造了一个结构体,其中有两个元素a表示花色,b表示大小。对于花色的大小以及数字的大小比较比较麻烦,在这里,我们同样可以利用map,将规定的大小比较转移到int型上,这样我们对于结构体进行符号重载是显得尤为方便,另外也使得我们对于每一个人手里的牌可以进行快速排序(此时用到sort函数);另外,本题的牌的读入只需要限制每人每次读两张即可。对于其他部分,只需要简单地利用条件与循环语句即可。
代码:

#include<iostream>
#include<string.h>
#include<map>
#include<algorithm>
using namespace std;
map<char,int>mp;
struct node {
	char a,b;//a表示花色;
	node() {
	}
	node(char _a,char _b):a(_a),b(_b) {

	}
	bool operator<(const node&p)const {
		if(a!=p.a) {
			return mp[a]<mp[p.a];
		} else
			return mp[b]<mp[p.b];
	}
};
node* E=new node[13];
node* S=new node[13];
node* W=new node[13];
node* N=new node[13];
void print1() {
	for(int i=0; i<13; i++) {
		cout<<"---+";
	}
	cout<<endl;
}
void print2(int a) {
	if(a==1) {
		cout<<"South player:"<<endl;
		cout<<"+";
		print1();
		cout<<"|";
		for(int i=0; i<13; i++) {
			cout<<S[i].b<<" "<<S[i].b<<"|";
		}
		cout<<endl;
		cout<<"|";
		for(int i=0; i<13; i++) {
			cout<<" "<<S[i].a<<" "<<"|";
		}
		cout<<endl;
		cout<<"|";
		for(int i=0; i<13; i++) {
			cout<<S[i].b<<" "<<S[i].b<<"|";
		}
		cout<<endl;
		cout<<"+";
		print1();
	} else if(a==2) {
		cout<<"West player:"<<endl;
		cout<<"+";
		print1();
		cout<<"|";
		for(int i=0; i<13; i++) {
			cout<<W[i].b<<" "<<W[i].b<<"|";
		}
		cout<<endl;
		cout<<"|";
		for(int i=0; i<13; i++) {
			cout<<" "<<W[i].a<<" "<<"|";
		}
		cout<<endl;
		cout<<"|";
		for(int i=0; i<13; i++) {
			cout<<W[i].b<<" "<<W[i].b<<"|";
		}
		cout<<endl;
		cout<<"+";
		print1();
	} else if(a==3) {
		cout<<"North player:"<<endl;
		cout<<"+";
		print1();
		cout<<"|";
		for(int i=0; i<13; i++) {
			cout<<N[i].b<<" "<<N[i].b<<"|";
		}
		cout<<endl;
		cout<<"|";
		for(int i=0; i<13; i++) {
			cout<<" "<<N[i].a<<" "<<"|";
		}
		cout<<endl;
		cout<<"|";
		for(int i=0; i<13; i++) {
			cout<<N[i].b<<" "<<N[i].b<<"|";
		}
		cout<<endl;
		cout<<"+";
		print1();
	} else if(a==4) {
		cout<<"East player:"<<endl;
		cout<<"+";
		print1();
		cout<<"|";
		for(int i=0; i<13; i++) {
			cout<<E[i].b<<" "<<E[i].b<<"|";
		}
		cout<<endl;
		cout<<"|";
		for(int i=0; i<13; i++) {
			cout<<" "<<E[i].a<<" "<<"|";
		}
		cout<<endl;
		cout<<"|";
		for(int i=0; i<13; i++) {
			cout<<E[i].b<<" "<<E[i].b<<"|";
		}
		cout<<endl;
		cout<<"+";
		print1();
	}

}
int main() {
	mp['C']=0;
	mp['D']=1;
	mp['S']=2;
	mp['H']=3;
	mp['2']=4;
	mp['3']=5;
	mp['4']=6;
	mp['5']=7;
	mp['6']=8;
	mp['7']=9;
	mp['8']=10;
	mp['9']=11;
	mp['T']=12;
	mp['J']=13;
	mp['Q']=14;
	mp['K']=15;
	mp['A']=16;
	char s;
	string ss1;
	string ss2;
	cin>>s;
	while(s!='#') {
		cin>>ss1>>ss2;
		ss1=ss1+ss2;
		int j=0;
		if(s=='N') {
			for(int i=0; i<13; i++) {
				E[i].a=ss1[j++];
				E[i].b=ss1[j++];
				S[i].a=ss1[j++];
				S[i].b=ss1[j++];
				W[i].a=ss1[j++];
				W[i].b=ss1[j++];
				N[i].a=ss1[j++];
				N[i].b=ss1[j++];
			}
		}

		else if(s=='E') {
			for(int i=0; i<13; i++) {
				S[i].a=ss1[j++];
				S[i].b=ss1[j++];
				W[i].a=ss1[j++];
				W[i].b=ss1[j++];
				N[i].a=ss1[j++];
				N[i].b=ss1[j++];
				E[i].a=ss1[j++];
				E[i].b=ss1[j++];
			}

		} else if(s=='S') {
			for(int i=0; i<13; i++) {
				W[i].a=ss1[j++];
				W[i].b=ss1[j++];
				N[i].a=ss1[j++];
				N[i].b=ss1[j++];
				E[i].a=ss1[j++];
				E[i].b=ss1[j++];
				S[i].a=ss1[j++];
				S[i].b=ss1[j++];
			}

		} else {
			for(int i=0; i<13; i++) {
				N[i].a=ss1[j++];
				N[i].b=ss1[j++];
				E[i].a=ss1[j++];
				E[i].b=ss1[j++];
				S[i].a=ss1[j++];
				S[i].b=ss1[j++];
				W[i].a=ss1[j++];
				W[i].b=ss1[j++];
			}

		}
		sort(N,N+13);
		sort(S,S+13);
		sort(W,W+13);
		sort(E,E+13);
		print2(1);
		print2(2);
		print2(3);
		print2(4);
		cout<<endl;
		cin>>s;
	}
	return 0;
}在这里插入代码片
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值