题目
化学很神奇,以下是烷烃基。
假设如上图,这个烷烃基有6个原子和5个化学键,6个原子分别标号1~6,然后用一对数字 a,b 表示原子a和原子b间有一个化学键。这样通过5行a,b可以描述一个烷烃基。
你的任务是甄别烷烃基的类别。
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有2个1度顶点,4个2度顶点;
2-methylpentane有3个1度顶点,2个2度顶点,1个3度顶点;
3-methylpentane有3个1度顶点,2个2度顶点,1个3度顶点;
2,3-dimethylbutane有4个1度顶点,2个3度顶点;
2,2-dimethylbutane有4个1度顶点,1个2度顶点,1个4度顶点。
仅根据顶点的度无法区分2-methylpentane和3-methylpentane,故再根据2度和3度的点的连接情况区分二者:
2-methylpentane的3度顶点仅与1个2度顶点相连;
3-methylpentane的3度顶点与2个2度顶点相连。
使用二维矩阵atom[6][6]记录当前烷烃基的原子相连情况,使用数组degree[4]记录1~4度的点分别有几个,使用数组bi[3],tri[3]记录度分别为2、3的点的标号。若2度顶点bi[i]与3度顶点tri[j]相连,则atom[bi[i]][tri[j]]==1。
代码
#include <iostream>
#include <math.h>
#include <iomanip>
#include <algorithm>
#include <string.h>
using namespace std;
int main() {
int t;
cin>>t;
for(int i=0;i<t;i++){
int atom[6][6];
memset(atom, 0, sizeof(atom));
for(int j=0;j<5;j++){
int a,b;
cin>>a>>b;
atom[a-1][b-1]=1;
atom[b-1][a-1]=1;
}
int degree[4];//1~4度的点有几个
memset(degree, 0, sizeof(degree));
//根据2度和3度的点的连接情况再判断else
int tri[6],bi[6];
memset(tri, -1, sizeof(tri));
memset(bi, -1, sizeof(bi));
for(int j=0;j<6;j++){//编号为j的点的度
int count=0;
for(int k=0;k<6;k++){//遍历矩阵atom中j所在的行
if(atom[j][k]==1){//与编号为j的点相连
count++;
}
}
//j的度为count,度为count的点的个数+1
degree[count-1]++;
//若j的度为3,则记入数组tri[]
if(count==3){
tri[degree[2]-1]=j;//2=3-1
}
//若j的度为2,则记入数组bi[]
if(count==2){
bi[degree[1]-1]=j;//1=2-1
}
}
if(degree[0]==2&°ree[1]==4)
cout<<"n-hexane"<<endl;
else if(degree[0]==4&°ree[2]==2)
cout<<"2,3-dimethylbutane"<<endl;
else if(degree[0]==4&°ree[1]==1&°ree[3]==1)
cout<<"2,2-dimethylbutane"<<endl;
else{
if(atom[tri[0]][bi[0]]==1&&atom[tri[0]][bi[1]]==1)
cout<<"3-methylpentane"<<endl;
else
cout<<"2-methylpentane"<<endl;
}
}
}
总结
记录点的度时,可以使用二维数组degree[][],degree[i][j]=k表示度为i的点与k个度为j的点相连,用不同度的点的连接关系区分。
题目链接