codeforces 490B.Queue 解题报告

题目链接:http://codeforces.com/problemset/problem/490/B

题目意思:给出每个人 i 站在他前面的人的编号 ai 和后面的人的编号 bi。注意,排在第一个位置的人他前面是无人的!于是 a1 = 0。最后那个人的后面是木有人的,即 bn = 0。然后根据这些条件求出整个序列是如何排的,输出答案。

     这条题卡了好久.........啊........啊........啊

     首先很容易知道第二个位置的人的编号 和 倒数第二个人的位置编号。用一个aft[]数组记录,aft[ai] = bi。表示 bi 在 ai 后面。然后从第 2 个位置开始,4、6,...n-2, n 就可以根据aft[] 数组来填出奇数位置的具体id number了。然后就开始卡在如何确定第 1 个位置应该填的id number了。然后好不容易用一个 bef[] 数组来求 (bef[bi] = ai),即从倒数第2个位置推回去直到第1个位置。赛后才发现这样只能处理 n 为偶数的情况。

     这就表示一定要知道第 1 个位置具体填哪个 id number!知道之后 bef[] 数组就没必要使用了。

     用一个cnt[] 数组来保存 ai 和 bi 的出现次数,通过观察可以发现,除了第 1 个和最后 1 个位置的人的 id number 的次数是 1 之外,其他位置都会出现 2 次。那么问题就是如何正确选出填在第 1 个位置的人的 id number 了。发现最后 1 个位置的人的 aft[] 是没有值的,那么如果有值,这个人就是排在第 1 个位置啦~~~~然后就可以根据 aft[] 数组来填1, 3, 5, ..., n-1 位置的数了。

     想到 头 都快爆炸了 .............= =

     不知道为什么题目类型归为 graphs,我觉得像想法题多点

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int N = 1e6 + 5;
 8 const int maxn = 2e5 + 5;
 9 
10 int aft[N], cnt[N];
11 int res[maxn];
12 
13 int main()
14 {
15     #ifndef ONLINE_JUDGE
16         freopen("in.txt", "r", stdin);
17     #endif // ONLINE_JUDGE
18     int n, a, b, fst;
19     while (scanf("%d", &n) != EOF)
20     {
21         memset(aft, 0, sizeof(aft));
22         memset(cnt, 0, sizeof(cnt));
23 
24         for (int i = 1; i <= n; i++)
25         {
26              scanf("%d%d", &a, &b);
27              if (a == 0 && b != 0)
28                 res[2] = b;
29              else if (a != 0 && b == 0)
30              {
31                  fst = a;      // 这个很重要,因为有可能整个序列只有两个元素
32                  res[n-1] = a;
33              }
34              aft[a] = b;
35              cnt[a]++;
36              cnt[b]++;
37         }
38         for (int i = 0; i <= N; i++)
39         {
40             if (cnt[i] == 1 && aft[i] != 0)
41             {
42                  fst = i;
43                  break;
44             }
45         }
46         int tt = res[2];
47         for (int i = 4; i <= n; i += 2)      // 填偶数位置
48         {
49             if (aft[tt])
50             {
51                 res[i] = aft[tt];
52                 tt = res[i];
53             }
54         }
55         res[1] = fst;
56         tt = fst;
57         for (int i = 3; i <= n; i += 2)    // 填奇数位置
58         {
59             if (aft[tt])
60             {
61                 res[i] = aft[tt];
62                 tt = res[i];
63             }
64         }
65         for (int i = 1; i <= n; i++)
66             printf("%d ", res[i]);
67         puts("");
68     }
69     return 0;
70 }
View Code

     

     

原文地址:https://www.cnblogs.com/windysai/p/4117785.html