题目描述
假设如上图,这个烷烃基有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
思路分析:
根据题意,把每个原子看做一个点,化学键则是连接两个原子的边。用二维数组edge来表示是否有边,若edge[i][j]==1,则编号为i,j的两个点之间有连接。
因为原子类型与人为规定的原子编号无关,所以不应把编号作为分类依据。可以看出,不同种类的烷烃基每个点的度不同, n-hexane的最大度为2,度为1的点有2个;2,2-dimethylbutane的最大度为4,度为1的点有4个;2,3-dimethylbutane、3-methylpentane和2-methylpentane最大度均为3,但前一个度为1的点有4个,后两个度为1的点数相同,但3-methylpentane只有一个度为1的相邻点,而2-methylpentane有两个。
综上,通过for循环中通过比较得出最大度和度为1的点的个数,根据不同烷烃基特点输出名称。
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int count[7];//度
int edge[7][7];//边
for(int i=0;i<n;i++)
{
int a,b,index;//index为最大度的点的编号
int max=1;
int tag=0;
for(int j=0;j<7;j++)
{
count[j]=0;
for(int k=0;k<7;k++)
{
edge[j][k]=0;
}
}
for(int j=0;j<5;j++)
{
cin>>a>>b;
count[a]++;
count[b]++;
edge[a][b]=1;
edge[b][a]=1;
}
for(int j=1;j<7;j++)
{
if(count[j]>max)//比较得到最大度和度为1的点数
{
max=count[j];
index=j;
}
if(count[j]==1) tag++;
}
if(max==2)
{
cout<<"n-hexane"<<endl;
}
if(max==4)
{
cout<<"2,2-dimethylbutane"<<endl;
}
if(max==3&&tag==4)
{
cout<<"2,3-dimethylbutane"<<endl;
}
if(max==3&&tag==3)
{
for(int j=1;j<7;j++)
{//判断与最大度的点的相邻点的度是否为1,是则tag++
if(edge[index][j]==0) continue;
if(count[j]==1)
{
tag++;
}
}
if(tag==4)//只有一个相邻点度为1
{
cout<<"3-methylpentane"<<endl;
}
else
{
cout<<"2-methylpentane"<<endl;
}
}
}
}