UVA - 1623 Enter The Dragon(贪心)

题目:

思路:

读完题之后有了以下想法:

当遇到下雨的天,就找这个湖泊上一次下雨满了之后又一次不下雨的日期。有就在这个日期下记录被神龙喝干的湖的编号,没有就是不符合题意。

这个想法是对的,但是却被代码卡的死死的。知道看到了大佬用set写的……

set本身是有序的,而且也有二分查找的方法。

代码:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1e3
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int maxn = 1000100;
int rain[maxn],ans[maxn],pre[maxn];
int n,m;

int main(){
    //FRE();
    int kase;
    scanf("%d",&kase);
    while(kase--){
        memset(pre,0,sizeof(pre));//记录湖泊i上一次被灌满的日期
        memset(ans,0,sizeof(ans));//记录日期i喝干的湖泊的编号
        set<int> norain;
        set<int>::iterator p;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=m; i++){
            scanf("%d",&rain[i]);
        }

        bool ok = true;
        for(int i=1; i<=m; i++){
            if(rain[i]==0){
                norain.insert(i);//将不下雨的日期插入set
            }else{
                int t = rain[i];
                p = norain.lower_bound(pre[t]);//查找湖泊t上一次灌满之后有没有不下雨的日期
                if(p==norain.end()){
                    ok = false;
                    break;
                }else{
                    pre[t] = i;//更新湖泊t上一次被灌满的日期
                    ans[*p]=rain[i];//记录喝干的湖泊的编号
                    norain.erase(p);//删掉已经用掉的不下雨的日期
                }
            }
        }
        if(!ok){
            printf("NO\n");
        }else{
            printf("YES\n");
            int isfirst = 0;
            for(int i=1; i<=m; i++){
                if(!rain[i]){
                    if(isfirst++)printf(" ");
                    printf("%d",ans[i]);
                }
            }
            printf("\n");
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sykline/p/10352915.html
今日推荐