HRBUST 2078:糖果(模拟,贪心)

题不难,但作为一道恶心到了我的题,我还是记录一下的好。

题意: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;
}
原文地址:https://www.cnblogs.com/shinecheng/p/3636627.html