A - 化学 (编译器选 GNU G++)
题目描述
化学很神奇orz,以下是烷烃基:
假设如上图,这个烷烃基有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
每组数据,输出一行,代表烷烃基的英文名
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
单词一定不要写错,提交代码的时候一直wa,改了好久,最后才发现是单词打错了,遇到这类题目可以直接把题目中的输出复制过来避免此类错误。
思路
第1、4、5种都可以通过节点的度数特判,将题中化学结构看做无向连接图,输入时记录节点的邻接情况。cout记录每个节点的度(与多少个点相连)。
for(int i=1; i<=6; i++){
for(int j=1; j<=6; j++){
count[i] += map[i][j];
}
}
int mark =0;//1到5对应表示五种类型
int mark2;
for(int i=1; i<=6; i++){
if(count[i] == 4){
mark=5;break;
}
else if(count[i] == 3){
mark++;
mark2=i;
}
}
mark标记结构种类,其中第2、3种结构需要进一步判断,利用dfs从度为3的节点开始计算到边缘的步长,较长者为第二种,次长者为第三种。
else if(mark ==1 ){
int* visit=new int[7];
memset(visit, 0, 7* sizeof(int));
visit[mark2]=1;
//cout<<mark2<<endl;
stack<int> s;
bool b=false;//是否有长度为3;
for(int i=1; i<=6; i++){
int length=0;//最长步长;
while(! s.empty()) s.pop();
if(map[mark2][i] ==1 ){
s.push(i);
visit[i]=1;
length++;
}
while(! s.empty()){
int now=s.top();
s.pop();
for(int i=1; i<=6; i++){
if(map[now][i] == 1 && visit[i] != 1){//连接
s.push(i);
visit[i]=1;
length++;
//cout<<length<<endl;
if(length == 3)
b=true;
}
}
}
}
if(b == true)cout<<"2-methylpentane"<<endl;
else cout<<"3-methylpentane"<<endl;
}
代码
#include<iostream>
#include<string.h>
#include<cmath>
#include<stack>
using namespace std;
int main()
{
long T;//组数
cin>>T;
int key1,key2;
int map[7][7];
int count[7];//每一个点的连接情况;
while(T--){
for(int i=0; i<7; i++)//初始化
memset(map[i], 0, 7* sizeof(int));
for(int i=0; i<5; i++){//输入
cin>>key1>>key2;
map[key1][key2]=1;
map[key2][key1]=1;
}
memset(count, 0, 7* sizeof(int));
for(int i=1; i<=6; i++){
for(int j=1; j<=6; j++){
count[i] += map[i][j];
}
}
int mark =0;//1到5对应表示五种类型
int mark2;
for(int i=1; i<=6; i++){
if(count[i] == 4){
mark=5;break;
}
else if(count[i] == 3){
mark++;
mark2=i;
}
}
if(mark == 5)cout<<"2,2-dimethylbutane"<<endl;//
else if(mark == 0)cout<<"n-hexane"<<endl;//
else if(mark == 2)cout<<"2,3-dimethylbutane"<<endl;//
else if(mark ==1 ){
int* visit=new int[7];
memset(visit, 0, 7* sizeof(int));
visit[mark2]=1;
//cout<<mark2<<endl;
stack<int> s;
bool b=false;//是否有长度为3;
for(int i=1; i<=6; i++){
int length=0;//最长步长;
while(! s.empty())
{
s.pop();
}
if(map[mark2][i] ==1 ){
s.push(i);
visit[i]=1;
length++;
}
while(! s.empty()){
int now=s.top();
s.pop();
for(int i=1; i<=6; i++){
if(map[now][i] == 1 && visit[i] != 1)
{//连接
s.push(i);
visit[i]=1;
length++;
//cout<<length<<endl;
if(length == 3)
b=true;
}
}
}
}
if(b == true)cout<<"2-methylpentane"<<endl;
else cout<<"3-methylpentane"<<endl;
}
}
return 0;
}