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;
}

原文地址:https://www.cnblogs.com/sykline/p/10352915.html

时间: 2024-08-30 05:48:29

UVA - 1623 Enter The Dragon(贪心)的相关文章

UVa - 1623 - Enter The Dragon

The capital of Ardenia is surrounded by several lakes, and each of them is initially full of water. Currently, heavy rainfalls are expected over the land. Such a rain falls to one of the lakes: if the lake is dry and empty, then it will be filled wit

UVA 1623 Enther the Dragon 神龙喝水

贪心,每次遇到一个满水的湖要下暴雨的时候,就往前找之前最后一次满水之后的第一个没有下雨的且没有被用掉天day1. 因为如果不选这day1,那么之后的湖不一定能选上这一天.如果这一天后面还有没有下雨的天day2的话,选后面的,会使得day1到day2之前满水的湖选择减少. #include<bits/stdc++.h> #define PB push_back #define MP make_pair #define fi first #define second #define FOR(i,s

UVa1623 Enter The Dragon (贪心)

链接:http://bak2.vjudge.net/problem/UVA-1623 分析:用集合st保存当前还可以让神龙喝干湖水的日子,数组full[i]保存i号湖上次满水的日子.每当到了要往湖里下雨的日子,在集合st里查找这个湖最后一次满水的日子后第一个没被用掉不下雨的日子去喝干这个湖水,维护这个湖最后一次满水的日子,把用掉的日子从集合st里删除. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm

uva 1521 - GCD Guessing Game(贪心)

题目链接:uva 1521 - GCD Guessing Game 题目大意:给定一个数N,现在又一个数x,在1~N之间,现在每次可以猜一个数a,返回gcd(x,a),问说最少猜几次可以确定x. 解题思路:其实就将1~N里面的素数都要考虑一遍,因为有一个N的限制,所以每次选出来的素数的积不大于N即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const

uva 10026 Shoemaker&#39;s Problem(贪心+排序)

虽然是个水题,但是在一些细节上wa了几次,好像不支持'\b'退格符号,我用在了输出空格那,结果wa了...白白 wa了几次...题意是看的题解..今天只写了两道题,速度有点慢,得加快了,以后得先认真读懂题目,题目读懂了 就相当于做出来一半然后仔细动脑想想,有想法了再敲,不能盲目的做题.另外,热烈祝贺今天c++ primer看到 了100页 思路: 这道题是让给的数据是每件工作需要做的天数和每耽误一天所需要的费用,让求一个序列使得付费最小,如果有相同答 案把字典树最小的输出...输出的是序号,该件

uva 1016 - Silly Sort(置换+贪心)

题目链接:uva 1016 - Silly Sort 题目大意:给定一个长度为n的序列,每次操作可以交换任意两个数的位置,代价为两个数的和,求最小代价,将序列排成有序的. 解题思路:给定序列根据数的大小映射成一个置换,分解置换的循环,对于每个循环中,肯定是用值最小的逐个去交换的代价最小,但是要考虑,可以将最小的值与序列中最小值交换,用它代替去交换,最后再换回来.取两种情况中最优的. #include <cstdio> #include <cstring> #include <

uva 714 - Copying Books(贪心 最大值最小化 二分)

题目描述开头一大堆屁话,我还仔细看了半天..其实就最后2句管用.意思就是给出n本书然后要分成k份,每份总页数的最大值要最小.问你分配方案,如果最小值相同情况下有多种分配方案,输出前面份数小的,就像字典序输出从小到大一样的意思. 这里用到贪心的方法,定义f(x)为真的条件是满足x为最大值使n本书分成k份,那么就是求x的最小值.如何确定这个x就是用的二分法,x一定大于0小于所有值的合,不断的二分再判断是否成立,成立就取左半边,不成立说明太小了就取右半边,写的时候还是没有把二分法理解透彻,我还怕会丢失

uva:10670 - Work Reduction(贪心)

题目:10670 - Work Reduction 题目大意:给出n, m, L.n代表老板给的全部的paperworks的数量,m代表最终剩下的数量,L代表由这么多家公司需要你来计算最小的花费. 解题思路: 1.L家公司l行.每行由公司的名字 :A,B: A代表一份paperwork需要的money,B则代表帮你减少到总共的paperworks的数量一半要话费的money.注意这里是你手头上有的paperworks而不是老板要求你完成的数量,之前在这里卡了好久.还有减半不能导致最终的数量小于m

uva:10602 - Editor Nottoobad(贪心)

题目:10602 - Editor Nottoobad 题目大意:有一个机子它由press的动作还有copy和delete字符的动作.给一组字符串,问要输入这样的一组字符串,最少要执行的press动作. 解题思路:将这一组字符串按照ascall码排序后,这样前后两个字符串的相似度是比较高的.然后后一个字符串和前一个字符串相比,看有多少相同的可以copy,就只要统计一下不相同的字符个数.这题比较迷惑人的是题目一直说要求第一个字符串一定要先执行press动作,但是输出却可以任意给一种,不一定是要第一