WEEK2模拟题

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

思路
这个题的难处在于如何判断2-methylpentane和3-methylpentane,我们用一个矩阵记录原子之间的连接情况,通过度数很好的能分辨其他三个,在判断这两个时,我们要查看与3度原子相邻的原子之间的度数,如果是1和2则为2-methylpentane否则为3-methylpentane
代码如下:

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

const int maxn = 7;
int m[maxn][maxn];

int k[7][7];
int kk[7];
int kkk[6];
int a,b;
int s[3];

int main()
{
	int m;
	cin>>m;
	while(m--)
	{
		memset(k, 0,sizeof(k ));
		memset(kk,0,sizeof(kk));
		for(int i = 0;i<5;i++)
		{
			cin>>a>>b;
			k[a][b] = 1;
			k[b][a] = 1;
			kk[a]++;
			kk[b]++; 
		}
		memset(kkk,0,sizeof(kkk));
		for(int i = 1;i<=6;i++)
		{
			kkk[kk[i]]++;
		}
		if(kkk[2]==4)
		{
			cout<<"n-hexane"<<endl; 
		} 
		else if(kkk[4]==1)
		{
			cout<<"2,2-dimethylbutane"<<endl;
		}
		else if(kkk[3]==2)
		{
			cout<<"2,3-dimethylbutane"<<endl;
		}
		else if(kkk[3]==1)
		{
			int c;
			for(int i = 1;i<=6;i++)
			{
				if(kk[i]==3)
				{
					c = i;
				}
			}
			
			memset(s,0,sizeof(s));
			for(int i = 1;i<=6;i++)
			{
				if(k[c][i]==1)
				{
					s[kk[i]]++;
				}
			}
			if(s[1]==1)
			{
				cout<<"3-methylpentane"<<endl;
			}else if(s[2]==1){
				cout<<"2-methylpentane"<<endl;
			}
		}
	}
	
}

题目描述:
程序设计思维作业和实验使用的实时评测系统,具有及时获得成绩排名的特点,那它的功能是怎么实现的呢?
我们千辛万苦怼完了不忍直视的程序并提交以后,评测系统要么返回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个字符宽,右对齐)。名字、题数和时间分相互之间有一个空格。数据保证可按要求的输出格式进行输出。
思路:
这个题目本身不难,关键在于括号的处理,括号的处理我们可以用scanf特殊处理在这里我用的方法是用字符串处理。
第二个方面是怎么快速的根据他给定的格式进行排序,我们可以用到sort函数,我们可以定义结构体记录每个学生的题目的情况,在在里面定义一个题目中给定的罚时计算方法重载小于号。
代码如下:

#include<iostream>
#include<algorithm>
#include<iomanip>

using namespace std;

struct student{
	string name;
	int timescore;
	int score;
	student()
	{
		timescore=0;
		score = 0;
	}
	bool operator<(const student a)
	{
		if(score!=a.score) return score>a.score;
		else if(timescore!=a.timescore) return timescore<a.timescore;
		else return name[0] < a.name[0]; 
	 } 
}; 

student* students;

int main()
{
	int m,n;
	cin>>m>>n;
	students = new student[1000];
	int cnt = 0;
	string a;
	char name[10];
	int count = 0;
	while(cin>>a)
	{
		
		students[cnt].name = a;
		int s = 0;
		for(int i = 0;i < m;i++)
		{
			cin>>a;
			if(a[0]=='-'||a[0]=='0') continue;
			else
			{
				s++;
				int c=0;int b=0;
				int i = 0;
				for(;a[i]!='('&&i<a.length();i++)
				{
						c = c*10 + (a[i]-'0');
				}
				i++;
				for(;a[i]!=')'&&i<a.length();i++)
				{
					b = b*10 + (a[i] -'0'); 
				}
				
				students[cnt].timescore += c + n*b;
			}
		}
		students[cnt].score = s;
		cnt++;
		count++;
	}
	sort(students,students + cnt);
	for(int i = 0;i<cnt;i++)
	{
		cout<<std::left<<setw(10)<<students[i].name<<" ";
		cout<<std::right<<setw(2)<<students[i].score<<" ";
		cout<<std::right<<setw(4)<<students[i].timescore;
		cout<<endl;
	}
	return 0;
	
	//<<setiosflags(ios::left)
}

题目描述:
四个人在一起打牌,坐在四个方向North,East,South,West。指定一个发牌员开始发一套扑克牌(52张),按顺时针发牌,从发牌员的下一位开始发起。牌的顺序:花色是(梅花)<(方片)<(黑桃)<(红桃),(输入时,我们用C,D,S,H分别表示梅花,方片,黑桃,红桃,即其单词首字母)。对于牌面的值,我们规定2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A。 要求按从小到大的顺序对四个人的牌进行排序,然后按给定格式输出。
输入:每组数据的第一行包含一个大写字符,表示发牌员是谁。如果该字符为‘#’则表示输入结束。
接下来有两行,每行有52个字符,表示了26张牌,两行加起来一共52张牌。每张牌都由两个字符组成,第一个字符表示花色,第二个字符表示数值。

思路描述:
模拟题我们需要考虑的就是怎么把形象化的东西转换为数字和逻辑的表达,比如这道题,我们分析,转着圈发牌就好比一个首尾相接的圆环,而这种实现方式我们通常用取模的方式来实现,第二,记录数字和花色,我们知道一共有14中数字,五种花色,而这里我们就可以用给花色置一个倍数让他在加上数字,倍数的挑选一定要保存数字的所有信息,保证在取模的时候不丢失,所以只要倍数大于等于15就可以

代码如下:

#include<cstdio>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<vector>

using namespace std;

char hu[7] = {'0','C','D','S','H'};
char su[20] = {'0','1','2','3','4','5','6','7','8','9','T','J','Q','K','A'};
vector<int> s[4];

int num(char a,char b)
{
	int m,n;
	switch(a){
		case 'C':
			m = 1;break;
		case 'D':
			m = 2;break;
		case 'S':
			m = 3;break;
		case 'H':
			m = 4;break;
		}
	if(b>='0'&&b<='9')
		n = b-'0';
	switch(b){
		case 'T':
			n = 10;break;
		case 'J':
			n = 11;break;
		case 'Q':
			n = 12;break;
		case 'K':
			n = 13;break;
		case 'A':
			n = 14;break;
		}
	return m*15+n;
}

int main()
{
	char weizhi;
	while(cin>>weizhi)
	{
		int cnt;
		if(weizhi == '#') return 0;
		switch(weizhi){
		case 'S':
			cnt = 0;break;
		case 'W':
			cnt = 1;break;
		case 'N':
			cnt = 2;break;
		case 'E':
			cnt = 3; break;
		}
		for(int i = 0;i<4;i++)
		{
			s[i].clear();
		}
		cnt++;
		cnt = cnt%4;
		char hua,shu;
		getchar();
		for(int i = 0;i<26;i++)
		{
			hua = getchar();
			shu = getchar();
			int n = num(hua,shu);
			s[cnt].push_back(n);
			cnt++;
			cnt = cnt%4;
		}
		getchar();
		for(int i = 0;i<26;i++)
		{
			hua = getchar();
			shu = getchar();
			int n = num(hua,shu);
			s[cnt].push_back(n);
			cnt++;
			cnt = cnt%4;
		}	
		sort(s[0].begin(),s[0].end());
		sort(s[1].begin(),s[1].end());
		sort(s[2].begin(),s[2].end());
		sort(s[3].begin(),s[3].end());
		for(int j = 0;j <4 ;j++)
		{	
			if(j==0)	cout << "South player:" << endl;
			if(j==1)	cout << "West player:"  << endl;
			if(j==2)	cout << "North player:" << endl;
			if(j==3)	cout << "East player:"  << endl;
			cout << "+---+---+---+---+---+---+---+---+---+---+---+---+---+" << endl;
			
			for(vector<int>::iterator i = s[j].begin();i!=s[j].end();i++)
			{
				cout<<"|"<<su[(*i)%15]<<" "<<su[(*i)%15];
			}
			cout<<"|"<<endl;
			for(vector<int>::iterator i = s[j].begin();i!=s[j].end();i++)
			{
				cout<<"|"<<" "<<hu[(*i)/15]<<" ";
			}
			cout<<"|"<<endl;
			for(vector<int>::iterator i = s[j].begin();i!=s[j].end();i++)
			{
				cout<<"|"<<su[(*i)%15]<<" "<<su[(*i)%15];
			}
			cout<<"|"<<endl;
			cout << "+---+---+---+---+---+---+---+---+---+---+---+---+---+" << endl;
		}
		cout<<endl;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值