Week2 实验 A 化学 Gym-270437A 模拟

题目描述

化学很神奇,以下是烷烃基。

在这里插入图片描述

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

每组数据,输出一行,代表烷烃基的英文名

Sample Input

2
1 2
2 3
3 4
4 5
5 6
1 4
2 3
3 4
4 5
5 6

Sample Output

n-hexane
3-methylpentane

算法/思路分析

​ 题意为:根据原子之间的相连关系,判断属于图中的哪个类型。属于模拟题。仔细观察,可以发现,不同类型的烷烃基中,原子的度大多不同。例如:n-hexane中度为:1 2 2 2 2 1, 2-methylpentane中度为:1 1 3 2 2 1。然而,2-methylpentane与3-methylpentane的度均为:1 1 3 2 2 1, 由此无法判断。再继续观察,可以发现:2-methylpentane中,度为3的点连接的点的度为:1 1 2, 而3-methylpentane中,度为3的点连接的点的度为:2 2 1。故只需特判度为3的点周围的三个点中,度为2的点的个数即可区分这两者。由此,问题得解。

代码

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector> 
#include <cstring>
#include <string> 
using namespace std;
const int maxn = 2e5+10;

int cont[7];//cont[i]记录第i个点的度数 
int num[5]; //num[i]表示度为i的点的个数 
int G[7][7]; //记录两点之间是否相连 
string s[5] = {{"n-hexane"},{"2-methylpentane"},{"3-methylpentane"},{"2,3-dimethylbutane"},{"2,2-dimethylbutane"}};

//区分类型 
int dif()
{
	if(num[4] == 1) return 4;
	else if(num[3] == 2) return 3;
	else if(num[2] == 4) return 0;
	//特判 
	else 
	{
		int pp;
		//找到度为3的点 
		for(int i = 1; i <= 6; i++) if(cont[i] == 3) 
			pp = i;
		
		//找到度为3的点相连的其它3个点 
		int c[4] = {0};
		int n = 1;
		for(int i = 1; i <= 6; i++)
		{
			if(G[i][pp] == 1 || G[pp][i] == 1)
			{
				c[n++] = i; 
			}
		}
		//cout << c[1]  << " " << c[2] << " " << c[3] << endl;
		//统计这3个点的度数 
		int k[4] = {0};
		k[cont[c[1]]]++;k[cont[c[2]]]++;k[cont[c[3]]]++;
		//通过点的度数是2 2 1还是 1 1 2 判断类型 
		if(k[2] == 2) return 2;
		else return 1;
	}

}

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		//初始化 
		memset(G,0,sizeof(G));
		memset(num,0,sizeof(num));
		memset(cont,0,sizeof(cont));
		
		int x,y;
		for(int i = 1; i <= 5; i++)
		{
			scanf("%d%d",&x,&y);
			G[x][y] = 1;
			cont[x]++;
			cont[y]++;
		}
		
		/*for(int i = 1; i <= 6; i++)
			for(int j = 1; j <= 6; j++)
				cout << i << " " << j  << " "<< G[i][j] << endl;
		*/
		
		//分布统计度数为1,2,3,4,5,6的点的个数 
		for(int i = 1; i <= 6; i++)
			num[cont[i]]++;
		
		//判断类型 
		int tt = dif();
		cout << s[tt] << "\n";
	}
	return 0;
}
/*
5
1 2
2 3
3 4
4 5
5 6
1 2
2 3
2 4
4 5
5 6
1 2
2 3
3 4
3 5
5 6
1 3
2 3
3 4
4 5
4 6
1 3
2 3
3 4
3 5
5 6
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值