题目等网上更新出来了再贴吧
记得我看这个题挺早的,但当时压根就没看懂
我觉得这也是我的一个问题:太着急
刚开始总想找一道简单易懂的水题,这种思路是对的,但是再找的过程中也要试着去认真理解题意
做这个题的时候我们就只剩最后一个小时了
趁着峻峥出去尿尿的时候我认真读题,总算把题目给读懂了
就是给你一棵树,每次找到度数为1的节点中节点权值最小的,输出其出度所对应节点的权值
一直重复这个过程即可
这个题其实就是一个图,如果想着建树那就大错特错了
我的想法就是建图的同时记录每个节点的度数,每次取度数为1的节点中最小权值对应节点输出相应节点权值即可
说实话知道题意就是很水的一个题了,结果我们调了40+分钟,导致最后交题的时候就只剩几分钟了
看到AC的时候我们三个(我,峻峥,小明)真的异口同声的叫了出来
代码如下:
#include <stack>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 1010
#define ll long long
using namespace std;
char str[MAXN];
int map[MAXN][MAXN];
int ct[55];//用来记录节点i的度数
int ret[55];//用来保存最后的结果
stack<int> s;
int main(void) {
while(gets(str)) {
int num = 0;
memset(map, 0, sizeof(map));
int len = strlen(str);
for(int i=0; i<len; ++i) {
if(str[i] == '(') {
int d;
++num;
sscanf(str+i+1, "%d", &d);
//交题的时候一直WA,原因就是原来进栈的方式是str[i]-'0',这明显只能处理一位字符
//峻峥改成这样我们就过了,我觉得这个方法很值得借鉴,如果当时只有我一个的话估计就跪了
s.push(d);
}
else if(str[i] == ')') {
int top1 = s.top();
s.pop();
if(s.size() == 0)
continue;
int top2 = s.top();
map[top2][top1] = 1;
map[top1][top2] = 1;
++ct[top1];
++ct[top2];
}
}
int k = 0;
int tnum = num;
while(1) {//之所以有这个循环是要保证每次都要从小数字向大数字遍历,
//不然对于第一个样例最后的8不会输出,因为最后只剩两个节点2 8,而此时遍历到8所以会输出2
//我们队就因为这个问题一直在调!!
if(num == 1)
break;
int flag = 0;
for(int i=1; i<=tnum; ++i) {
if(ct[i] == 1) {
for(int j=1; j<=tnum; ++j) {
if(map[i][j] == 1) {
ret[k++] = j;
--ct[i];
--ct[j];
map[i][j] = map[j][i] = 0;
flag = 1;
num--;
break;
}
}
if(flag == 1)
break;
}
if(flag == 1)
break;
}
}
printf("%d", ret[0]);
for(int i=1; i<k; ++i) {
printf(" %d", ret[i]);
}
printf("\n");
}
return 0;
}