题不难,但作为一道恶心到了我的题,我还是记录一下的好。
题意:n个人围一圈,要求:相邻两人,分数高的要比分数低的得到更多的糖果,若分数相同则必须得到相同数量的糖果。问满足要求的最少需要分配的糖果数。(N<10^6)
思路:
从最分数最小的人开始分配(当然要很小气的只给1个啦),然后慢慢分,在满足要求的情况下给最小。
实现起来细节稍微有点多。具体实现思路如下:
1:压缩。把相同分数且相邻的多人压缩成一人
2:用一个备份,sort,得到分数从小往大的顺序。
3:按上面的顺序缩糖果。4种情况:[左》中》右]--右+1; [左《中〈右]--左+1; [左《中》右]--max(左,右)+1; [左》中《右]--1
OVER
收获:慢慢理,实现不是问题,相信自己的实现实力。。。。嗯嗯嗯
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 1000010 struct AA{ int id; int v; int num; }a[N], stk[N]; bool cmpV(const AA &a, const AA &b) { return a.v < b.v; } int main(){ int n; while (scanf("%d", &n) != EOF) { for (int i = 0; i < n; i++) { scanf("%d", &a[i].v); a[i].num = 1; } int top = 0; stk[top++] = a[0]; for (int i = 1; i < n; i++) { if (stk[top-1].v == a[i].v) stk[top-1].num++; else stk[top++] = a[i]; } if (top>1 && stk[top-1].v == stk[0].v) { stk[0].num += stk[top-1].num; top--; } for (int i = 0; i < top; i++) { stk[i].id = i; a[i] = stk[i]; } sort(stk, stk+top, cmpV); for (int i = 0; i < top; i++) { int id2 = stk[i].id; int id1 = (id2-1+top)%top; int id3 = (id2+1)%top; if (a[id1].v > a[id2].v && a[id2].v > a[id3].v) { a[id2].v = a[id3].v+1; } else if (a[id1].v < a[id2].v && a[id2].v < a[id3].v) { a[id2].v = a[id1].v+1; } else if (a[id1].v < a[id2].v && a[id2].v > a[id3].v) { a[id2].v = max(a[id1].v,a[id3].v)+1; } else if (a[id1].v > a[id2].v && a[id2].v < a[id3].v) { a[id2].v = 1; } } long long ans = 0; for (int i = 0; i < top; i++) { ans += a[i].v*1ll*a[i].num; } printf("%lld ", ans); } return 0; }