标签: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 }
标签:cto priority list define 避免 poi include namespace std
原文地址:http://www.cnblogs.com/Sdchr/p/7531296.html