Enter The Dragon UVA - 1623

题意:n个湖,每个湖都装满了水。不久的将来会有暴雨,在接下来的m天内,每天要么不下雨,要么恰好忘一个湖里下暴雨。如果这个湖里已经装满了水,将会引发水灾。没了避免水灾,神龙可以在每个不下雨的天里喝干一个湖的水(也可以不喝)。如果以后再往这个干枯的湖里下暴雨,湖会重新被填满,但不会引发水灾。神龙应当如何喝水才能避免水灾?n<=1e6,.<=1e6

思路:贪心,因为要优化时间复杂度,所以用set集合,本身有序,且可以二分查找。如果某天湖下雨,那么查找它上一次满候是否有不下雨的天让神龙喝水

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define mod 1000000007;
using namespace std;
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
const int maxn = 1e6 + 2;
set<int> day;
int n,m,x,ans[maxn],full[maxn];
int main()
{
    int T; scanf("%d",&T);
    while(T--)
    {
        day.clear();
        bool sign = true;
        scanf("%d%d",&n,&m);
        memset(ans,0,sizeof(ans));
        memset(full,0,sizeof(full));
        for(int i = 0;i < m;i++)
        {
            scanf("%d",&x);
            if(!sign) continue;
            if(!x) day.insert(i);//没下雨,闲置天数+1
            else
            {
                ans[i] = -1;
                set<int>::iterator it = day.lower_bound(full[x]);
                if(it == day.end()) sign = false;
                else
                {
                    ans[*it] = x;
                    full[x] = i;
                    day.erase(*it);
                }
            }
        }
        if(!sign) printf("NO\n");
        else
        {
            bool fir = false;
            printf("YES\n");
            for(int i = 0;i < m;i++)
            {
                if(ans[i] >= 0)
                {
                    if(!fir)
                    {
                        printf("%d",ans[i]);
                        fir = true;
                    }
                    else printf(" %d",ans[i]);
                }
            }
            printf("\n");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sgsyacm/article/details/87373102