题意
6个碳原子的碳链有上图所示的五种排列方法,6个原子分别用数字1~6表示(无顺序),给出化学键的连接,要求判断是哪一种烷烃基
样例
样例输入:
输入第一行为T,表示有T组数据,每组数据有5行,每行两个数字a,b 表示a和b之间有化学键
2
1 2
2 3
3 4
4 5
5 6
1 4
2 3
3 4
4 5
5 6
样例输出:
输入对应的烷烃基的名称,每行输出一个名称
n-hexane
3-methylpentane
思路
首先看到题的时候,我观察发现通过判断连接化学键最多的那个原子连接了多少化学键以及另外一些特性,就能直接判断出来是哪一种烷烃基
一开始我的想法是这样的(用d[i]表示每一个原子连接的化学键数):
先将d[]数组sort一下(升序排列)
d[6]= =4 -->2,2-dimethylbutane
d[6]= =3 && d[5] = =3 --> 2,3-dimethylbutane
d[6]= = d[5]= =d[4]= = d[3]= = 2 -->n-hexane
然后我突然发现 阿嘞?3-methylpentane 和 2-methylpentane 咋分不开了
然后我心想着,偷鸡都偷到这了,总不能写个机(ben)智(bi)的搜索啥的吧 就接着观察这两个可爱的烷烃基,发现了两者的不同:老三和老二虽然都是有一个原子连了三个化学键,但是老三连的那三个原子,他们化学键之和为5,而老二的是4 所以我就把他两个又区分出来啦~
不过为了区分他俩,我用了三个数组 d[],d2[],m[][]
d[]数组和d2[]数组一开始都是用来计算每个点的度(即连接的化学键数目)的 但我既需要排序,又要记录他们之间的连接情况 于是我的想法是d[]数组排序用来判断前面几种情况,d2[]数组的下标就是原子的标号,如果d2[i]= =3 && m[i][j]= =1 那么sum+=d2[j] 然后判断sum= =5 还是= = 4就好啦
总结
这个解题思路只能适用于本题,不具有普适性,如果原子的个数多了,就没办法这样做了,看到同学们有讨论用搜索做的?emmm可能也行叭
这道题的核心思想…观察法?(orz) 其实说了这么多 代码还是超简洁的 ^ ^
代码
#include<iostream>
#include<algorithm>
#include<math.h>
#include<stdio.h>
#include<string.h>
using namespace std;
int d[10],d2[10];
int m[7][7];
void check()
{
sort(d+1,d+7);
if(d[6]==4) {cout<<"2,2-dimethylbutane"<<endl; return;}
if(d[6]==3&&d[5]==3){cout<<"2,3-dimethylbutane"<<endl; return;}
if(d[6]==2&&d[5]==2&&d[4]==2&&d[3]==2) {cout<<"n-hexane"<<endl;return;}
int sum=0;
for(int i=1;i<=6;i++)
{
if(d2[i]==3)
{
for(int j=1;j<=6;j++)
{
if(m[i][j])
sum+=d2[j];
}
break;
}
}
if(sum==5) {cout<<"3-methylpentane"<<endl;return;}
if(sum==4) {cout<<"2-methylpentane"<<endl;return;}
}
int main()
{
int T;
cin>>T;
while(T--)
{
memset(d,0,sizeof(d));
memset(d2,0,sizeof(d));
memset(m,0,sizeof(m));
int a,b;
for(int i=1;i<=5;i++)
{
cin>>a>>b;
d[a]++;d[b]++;d2[a]++;d2[b]++;
m[a][b]=m[b][a]=1;
}
check();
}
return 0;
}