A-化学烷烃基种类甄别

题目:

化学很神奇,以下是烷烃基。
在这里插入图片描述

假设如上图,这个烷烃基有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用来存储每个化学键,每个原子以及其相邻接的原子形成一条链表,将输入的若干对顶点初始化为无向图。然后遍历该无向图,查询每个原子对应链表的长度并记录,即统计每个原子连接碳原子个数。

  • 当存在链表长度为4时,即有原子连接4个碳原子,为2,2-dimethylbutane。

  • 当存在2条链表长度为3时,即有2个原子连接3个碳原子,为2,3-dimethylbutane。

  • 当存在1条链表长度为4时,即有1个原子连接3个碳原子,此时有两种情况,其区别在于(该连接3个碳原子的原子) 连接 (连接2个碳原子的原子个数)(有点绕哈…所以用括号断一下下句)
    连接2个碳原子的原子个数1个时为2-methylpentane;2个时为3-methylpentane。

  • 剩下那个就是不存在连接3个碳原子和四个碳原子的 n-hexane啦。

代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

struct edge//邻接链表节点 
{
	int a;//起点 
	int b;//终点 
	edge *next;
};
//edge *table[6]; //每个数组元素是一个链表 
edge *firstnode[6];//每条链表首节点 
int listsize[12];//每条链表长度 

void initial(int aa,int bb)//构建无向图 
{
	edge *temp=new edge;
	temp->a=aa;
	temp->next=firstnode[bb];
	firstnode[bb]=temp;
	listsize[aa]++;
	
	edge *temp1=new edge;
	temp1->a=bb;
	temp1->next=firstnode[aa];
	firstnode[aa]=temp1;
	listsize[bb]++;
} 
int main()
{
	int T;
	int x,y,z,w;
	cin>>T;	
	while(T--)
	{		
		x=y=z=w=0;
		memset(listsize,0,sizeof(listsize));//初始化链表长度数组
		for(int i=1;i<=6;i++)//初始化链表首节点数组(一定要记得初始化哦,之前忘了初始化提交会报wronganswer)
		{
			firstnode[i]=NULL;
		}
		for(int i=1;i<=5;i++)
		{
			int aa,bb;
			cin>>aa>>bb;
			initial(aa,bb);  
		}
		int kk=0;
		for(int i=1;i<=6;i++)//遍历链表长度数组,统计各个数量的链表长度的个数
		{ 
			if(listsize[i]==1)
			{
				x++;
			}
			else if(listsize[i]==2)
			{
				y++;
			}
			else if(listsize[i]==3)
			{
				kk=i;
				z++;
			}
			else if(listsize[i]==4)
			{
				w++;
			}
		}
		if(w==1)
		{
			cout<<"2,2-dimethylbutane"<<endl;
		}
		if(z==2)
		{
			cout<<"2,3-dimethylbutane"<<endl;
		}
		if(y==4)
		{
			cout<<"n-hexane"<<endl;
		}
		if(z==1)
		{
			int tt=0; 
			for(edge *u=firstnode[kk];u!=NULL;u=u->next)
			{
				if(listsize[u->a]==2)
				{					
					tt++;
				}
			}
			if(tt==2)
			{
				cout<<"3-methylpentane"<<endl;
			}
			else if(tt=1)
			{
				cout<<"2-methylpentane"<<endl;
			}
		}
	}
	return 0;
} 

样例运行:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值