烷烃基的类别
问题描述
化学很神奇,以下是烷烃基。
Name |
HDMG |
Name |
HDMG |
n-hexane |
|
2-methylpentane |
|
3-methylpentane |
|
2,3-dimethylbutane |
|
2,2-dimethylbutane |
|
- |
- |
假设如上图,这个烷烃基有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
是同一种,本质上就是一条链,编号其实是没有关系的,可以在纸上画画就懂了
输入第一行为数据的组数 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
|
解题思路
对烷烃基标号
对于每一个标号可以用数组标号+1
表示,其连接的其他碳原子标号-1
用链表储存。
对于上述5种烷烃基,可以得到如下邻接链表结构:
| Name | HDMG | Structure |
| ————————— | ——————————— | —————————————————————————————— |
| n-hexane | | [1]→2
[2]→1→3
[3]→2→4
[4]→3→5
[5]→4→6
[6]→5
|
| 2-methylpentane | | [1]→2
[2]→1→3→4
[3]→2
[4]→2→5
[5]→4→6
[6]→5
|
| 3-methylpentane | | [1]→2
[2]→1→3
[3]→2→4→5
[4]→3
[5]→3→6
[6]→5
|
| 2,3-dimethylbutane | | [1]→2
[2]→1→3→4
[3]→2
[4]→2→5→6
[5]→4
[6]→4
|
| 2,2-dimethylbutane | | [1]→2
[2]→1→3→4→5
[3]→2
[4]→2
[5]→2→6
[6]→5
|
初次鉴别
标号不管怎么变都无法影响烷烃基的种类,但是观察邻接链表,不难发现链长可以进行初次区分。
| 正己烷 | 2-甲基苯丙烷 | 3-甲基苯丙烷 | 2,3-二甲基丁烷 | 2,2-二甲基丁烷 |
| :——: | :—————: | :—————: | :——————: | :——————: |
| 1 | 1 | 1 | 1 | 1 |
| 2 | 3 | 2 | 3 | 4 |
| 2 | 1 | 3 | 1 | 1 |
| 2 | 2 | 1 | 3 | 1 |
| 2 | 2 | 2 | 1 | 2 |
| 1 | 1 | 1 | 1 | 1 |
可以设3个int
变量count2, count3, count4
用来记录链长 = x
的出现次数。
只有2,2-dimethylbutane的count4 = 1
;
只有n-hexane的count2 = 4
;
只有2,3-dimethylbutane的count3 = 2
;
对于2-methylpentane和3-methylpentane,count2 = 2, count3 = 1, count4 = 0
,无法通过链长来区分。
- 鉴别2-methylpentane和3-methylpentane
不难发现,不管怎么编号(正/反),当链长 = 3
时,与这个碳原子相连的甲基个数不同。因此可记录链长 = 3
时数组编号no
,然后找到此数组所在的链arr[no]
,记录该条链储存的元素,即记录与之相连的碳原子的编号。
比如图中2-methylpentane与2
相连的是1, 3, 4
,属于甲基(即链长 = 1
)的是1, 3
;
3-methylpentane与3
相连的是2, 4, 5
,属于甲基的是4
。
2-methylpentane的甲基个数为2,3-methylpentane的甲基个数为1,以此鉴别。
数据结构及实现方法
采用邻接链表表示的有向图,本题只需提供插入、查找、遍历操作。详见源代码注释。
源代码
#include <iostream> #include <string> #include <vector> using namespace std;
struct node { int a; node* next; node() { a = 0; next = NULL; } node(const int& a) { this->a = a; next = NULL; } node(const int& a, node* next) { this->a = a; this->next = next; } };
class chain { protected: node* firstNode; int listSize; public: chain(int initialCapacity = 10) { firstNode = NULL; listSize = 0; } chain(const chain&); ~chain() { while (firstNode != NULL) { node* nextNode = firstNode->next; delete firstNode; firstNode = nextNode; } } int getSize() { return listSize; } void insert(const int& theElement) { if (firstNode == NULL) firstNode = new node(theElement, firstNode); else { node* p = firstNode; node* pp = NULL; while (p != NULL && p->a < theElement) { pp = p; p = p->next; } node* newNode = new node(theElement, p); if (pp == NULL) firstNode = newNode; else pp->next = newNode; } listSize++; } int indexOf(const int& theElement) const { node* currentNode = firstNode; int index = 0; while (currentNode != NULL && currentNode->a != theElement) { currentNode = currentNode->next; index++; } if (currentNode == NULL) return -1; else return index; } vector<int> getElement() { vector<int> nei; node *p = firstNode; while (p != NULL) { nei.push_back(p->a); p = p->next; } return nei; } };
class ane { private: chain arr[6]; int chainSize[6]; public: ane(){ } ~ane(){ } void insert(int a, int b) { if (arr[a].indexOf(b) == -1) { arr[a].insert(b); } } void getSize() { for (int i = 0; i < 6; i++) { chainSize[i] = arr[i].getSize(); } } string type() { int count2 = 0, count3 = 0, count4 = 0;
for (int i = 0; i < 6; i++) { if (chainSize[i] == 2) count2++; if (chainSize[i] == 3) count3++; if (chainSize[i] == 4) count4++; } if (count2 == 4) return "n-hexane"; if (count4 == 1) return "2,2-dimethylbutane"; if (count3 == 2) return "2,3-dimethylbutane"; else if (count2 == 2 && count3 == 1 && count4 == 0) { int no = 0; for (int i = 0; i < 6; i++) if (chainSize[i] == 3) no = i; vector<int> nei = arr[no].getElement(); int count1 = 0; for (int i = 0; i != nei.size(); i++) if (chainSize[nei.at(i)] == 1) count1++; if (count1 == 2) return "2-methylpentane"; else return "3-methylpentane"; }
} };
int main() { int n; cin >> n; for (int i = 0; i < n; i++) { ane tane; for (int j = 0; j < 5; j++) { int a, b; cin >> a >> b; tane.insert(a - 1, b - 1); tane.insert(b - 1, a - 1); } tane.getSize(); cout << tane.type() << endl; }
return 0; }
|