码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ 3523] [POI 2014] Bricks

时间:2017-09-16 16:10:33      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:cto   priority   list   define   避免   poi   include   namespace   std   

题意

  给定 n 种颜色, 第 i 种颜色有 c[i] 个.

  构造序列 L , 用完所有的颜色, L[1] = S, L[M] = E , 任意相邻两个都不同.

  n, m <= 1000000.

 

分析

  一点点来考虑, 如果不要求 L[1] = S, L[M] = E .

  每次我们肯定会尽可能选剩余次数大的, 因为这样才能尽可能避免出现相邻相同, 用堆维护每种的个数.

  如果要求 L[1] = S , 那么我们将 c[S] 减去 1 , 强制首位为 S 即可.

 

  如果要求末尾为 L[M] , 我们将 c[E] 减去 1, 强制末尾为 E .

  但是这样可能会导致倒数第二位与最后一位相同.

  我们将倒数第二位与倒数第三位交换, 倒数第 4 位与倒数第 5 位交换, ..., 以此类推, 直到不用交换.

  如果交换到 i <= 2 的时候, 仍然 L[i] = L[i+1] , 说明 E 的个数超过了一半, 所以一定无解.

 

  细节: 当 n = 1 的时候特判.

 

实现

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cctype>
 5 #include <queue>
 6 using namespace std;
 7 #define F(i, a, b) for (register int i = (a); i <= (b); i++)
 8 inline int rd(void) {
 9     int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -1;
10     int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-0; return x*f;
11 }
12  
13 const int N = 1000005;
14  
15 int n, S, E;
16 int M, cnt[N];
17 struct cmp { inline bool operator () (int i, int j) { return cnt[i] < cnt[j]; } };
18 priority_queue< int, vector<int>, cmp > q;
19 int List[N], tot;
20 int Last;
21  
22 inline void Maintain(int id) {
23     q.pop();
24     cnt[id]--;
25     if (cnt[id] > 0) q.push(id);
26     List[++tot] = id;
27     Last = id;
28 }
29  
30 int main(void) {
31     #ifndef ONLINE_JUDGE
32         freopen("klo.in", "r", stdin);
33     #endif
34      
35     n = rd(), S = rd(), E = rd();
36     F(i, 1, n) {
37         cnt[i] = rd();
38         M += cnt[i];
39     }
40      
41     if (M == 1) {
42         int Has = 1;
43         while (!cnt[Has]) Has++;
44         return printf("%d\n", Has == S && Has == E ? Has : 0), 0;
45     }
46      
47     cnt[S]--, cnt[E]--;
48     if (cnt[S] < 0 || cnt[E] < 0) return puts("0"), 0;
49     F(i, 1, n) if (cnt[i] > 0) q.push(i);
50     List[++tot] = S;
51     Last = S;
52     F(i, 2, M-1) {
53         int id = q.top();
54         if (id != Last)
55             Maintain(id);
56         else {
57             q.pop();
58             if (q.empty()) return puts("0"), 0;
59             int id2 = q.top();
60             Maintain(id2);
61             q.push(id);
62         }
63     }
64     List[++tot] = E;
65      
66     if (List[M-1] == List[M]) {
67         for (int i = M-1; i >= 1; i -= 2)
68             if (List[i] == List[i+1]) {
69                 if (i <= 2) return puts("0"), 0;
70                 swap(List[i-1], List[i]);
71             }
72             else break;
73     }
74      
75     F(i, 1, M) printf("%d ", List[i]); puts("");
76      
77     return 0;
78 }

 

[BZOJ 3523] [POI 2014] Bricks

标签:cto   priority   list   define   避免   poi   include   namespace   std   

原文地址:http://www.cnblogs.com/Sdchr/p/7531296.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!