Chieh's Blog

Because Of Coding

ZOJ Problem Set - 3888 Twelves Monkeys

Chieh posted @ 2015年7月29日 11:12 in ZOJ , 275 阅读

飞机票:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3888

题意:给你n年,其中有m中关系,Xi Yi,代表从第Xi年可以回到Yi年,其中 Xi>=Yi,然后给你Q个查询,每个查询一个年份q,问你从第q年,至少有两种方案可以回到q年之前的年份有多少年。然后后面就是给你解释,第q年可以等到q年之后然后在回到q年之前。或则直接走,但是m种关系在一条路径中只能用一次。

分析:假设当前查询的是q年,那么我们要知道我们能回到q年之前至少有两条路径有多少年,我们可以从q~n之间的最小Yi和次小Yi。为什么,因为q可以等到q~n之间的一年然后回到最小Yi,或则q可以等到q~n之间的一年然后回到次小Yi,这样就有两条路径可以回到Yi到q之间的年份,且因为次小Yi是第二小的,所以剩下的都大于次小Yi,所以次小Yi是最优的。那么就可以从后往前推,每次更新次小Yi。然后查询的话,如果次小Yi大于等于q,那么就是0,因为回不去,如果小于q,那么就可以会q-次小Yi年,这样的话就Ok了,最后啪啪啪就可以AC了

/*
Author:Chieh
Because Of Coding
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#define LL long long
#define INF 1e9
#define EPS 1e-9
using namespace std;
const int maxn=5*12345;
struct he
{
    int x,y;
} Sky[maxn];
int n,m,q;
bool cmp(he a,he b)
{

    return a.x>b.x;
}
void init()
{
    for(int i=1; i<=m; i++)scanf("%d%d",&Sky[i].x,&Sky[i].y);
    sort(Sky+1,Sky+1+m,cmp);
}
int ai[maxn];
void play()
{
    memset(ai,0,sizeof(ai));
    int l1=-1,l2=-1;
    for(int i=1; i<=m; i++)
    {
        int now=Sky[i].x;
        int next=Sky[i].y;
        if(l1==-1)l1=next;
        else if(l2==-1)
        {
            if(l1>next)
            {
                l2=l1;
                l1=next;
            }
            else
            {
                l2=next;
            }
        }
        else
        {
            if(next<l1)
            {
                l2=l1;
                l1=next;
            }
            else if(next<l2)
            {
                l2=next;
            }
        }
        ai[now]=l2;
    }

    for(int i=n; i>=1; i--)
    {
        if(ai[i]==-1)continue;
        if(ai[i]==0)
        {
            ai[i]=ai[i+1];
        }
    }
    int t;
    while(q--)
    {
        scanf("%d",&t);
        if(ai[t]==-1||ai[t]==0)printf("0\n");
        else
        {
            if(ai[t]>=t)printf("0\n");
            else printf("%d\n",t-ai[t]);
        }
    }
}
int main()
{
    while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    {
        init();
        play();
    }
//    cout << "Hello world!" << endl;
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter