题意:
上图是某一烷烃基的化学结构,该烷烃基有6个原子和五个化学键,六个原子编号为1~6,用一对数字 a,b 表示原子a和原子b间有一个化学键。
这样,用五对数字对可表示一个烷烃基。而我们的任务是甄别烷烃基的类别(图中五类)。原子没有特定的标号方式,如(1,2)、(2,3),(3,4)、(4,5)、(5,6)和(1,3)、(2,3)、(2,4)、(4,5)、(5,6)实质是同一种,都是链状烷烃基。
输入:
输入第一行为数据的组数T(1≤T≤200000)。每组数据有5行,每行是两个整数a, b(1≤a,b≤6,a ≤b) 。
数据保证,输入的烷烃基是以上5种之一。
Simple Input:2
1 2
2 3
3 4
4 5
5 6
1 4
2 3
3 4
4 5
5 6
输出:
每组数据,输出一行,代表烷烃基的英文名
Simple Output:
n-hexane
3-methylpentane
思路:
因为没有固定的标号形式,所以不能从点的标号入手,而应该从点与点之间的关系即化学键入手,化学键的个数是一定的,出现不同种类的烷烃基是因为不同类别中某一原子连接的化学键数目不同,即与某一原子连接的原子个数不同,经过观察可以发现,一个原子至少与一个原子之间有化学键,至多与四个原子之间有化学键,因此,我们建立一个有六个元素的数组,保存每个原子连接的原子数目,然后计算连接数分别为1,2,3,4的原子的个数。若连接数为4的原子数目为1,则为2,2-dimethylbutane;若连接数为4不存在而连接数为3的原子个数为2,则为2,3-dimethylbutane;若连接数为2的原子数目为4则为n-hexane,若连接数为3的原子个数为1,则需要分情况讨论,其中该原子(连接数为3的原子)的所有邻接原子的连接数总和为5则为3-methylpentane;否则,则为2-methylpentane。
代码:
#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
void judge(int *num[])
{
int a[7];
memset(a,0,sizeof(int)*7);
for(int i=0;i<5;i++)
{
a[num[i][0]]++;
a[num[i][1]]++;
}
int c[5];
memset(c,0,sizeof(int)*5);
for(int i=1;i<7;i++)
{
int temp=a[i];
c[temp]++;
}
if(c[4]==1)
{
printf("%s\n","2,2-dimethylbutane");
}
if(c[3]==2)
{
printf("%s\n","2,3-dimethylbutane");
}
if(c[2]==4)
{
printf("%s\n","n-hexane");
}
if(c[3]==1)
{
int temp;
for(int i=1;i<=6;i++)
{
if(a[i]==3)
{
temp=i;
break;
}
}
int number=0;
for(int i=0;i<5;i++)
{
if(num[i][0]==temp)
number+=a[num[i][1]];
if(num[i][1]==temp)
number+=a[num[i][0]];
}
if(number==5)
printf("%s\n","3-methylpentane");
else
printf("%s\n","2-methylpentane");
}
}
int main(int argc, char** argv) {
int n;
int**num=new int*[5];
for(int i=0;i<5;i++)
num[i]=new int[2];
scanf("%d",&n);
getchar();
for(int i=0;i<n;i++)
{
for(int i=0;i<5;i++)
{
scanf("%d %d",&num[i][0],&num[i][1]);
getchar();
}
judge(num);
}
return 0;
}