zoukankan      html  css  js  c++  java
  • man

    Description
    n间房子高度不同,Man 要从最矮的房子按照高度顺序跳到最高的房子,你知道房子的顺序,以及Man一次最远可以跳多远,相邻的房子至少有1的距离,房子的宽不计,现在由你安排相邻房子的距离,使Man可以跳到最高的房子且让最矮的房子与最高的房子距离最远,没有合法方案输出-1
    Input
    第一行一个整数T表示数据组数,每组数据第一行两个整数n,d分别表示房子数量以及Man一次可以跳多远,第二行n个整数用空格隔开,第i个整数表示第i个房子的高度
    Output
    每组数据输出‘Case ’+第几组数据+‘: ’+最远距离
    Sample Input
    样例输入:
    3
    4 4
    20 30 10 40
    5 6
    20 34 54 10 15
    4 2
    10 20 16 13

    样例输出:
    Case 1: 3
    Case 2: 3
    Case 3: -1
    HINT
    数据范围:
    对于40%的数据 n < 8 t=2 d < 10
    对于100%的数据 n < 10001 d < 1000000 t < 100 高度 < 1000000


    差分约束典型题…
    关于如何理解 选取起点和终点中靠左边的点, 开始跑一遍最短路就可以得到答案, 这里提供一种思路: 在跑最短路之前, dis被设置为INF, 跑最短路的过程就是为了使dis满足约束条件. 只要跑完最短路, dis[t]必定就是最大的. 至于为什么要选取起点和终点中靠左的开始跑最短路, 理由是dis[t]维护的是s到t的距离的最大值. 这个假如t在s的左边, 则距离为负, 则维护的实际上是t到s的距离的最小值. 因此要确保起始遍历的点在终结点的左边.

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<math.h>
    using namespace std;
    const int maxN = 1000;
    const int maxRoom = (int)1e6;
    struct building
    {
        int h, id;
    }a[maxN];
    int head[maxN];
    int top;
    struct edge
    {
        int v, w, next;
    }G[maxN << 2];
    void addEdge(int u, int v, int w)
    {
        G[top].v = v;
        G[top].w = w;
        G[top].next = head[u];
        head[u] = top ++;
    }
    int operator <(building x, building y)
    {
        return x.h < y.h;
    }
    int dis[maxN];
    int Q[maxRoom];
    int inQ[maxN];
    int vis[maxN];
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("man.in", "r", stdin);
        freopen("man.out", "w", stdout);
        #endif
        ios::sync_with_stdio(false);
        int T, _case = 0;
        for(cin >> T; T; T --)
        {
            int n, d;
            cin >> n >> d;
            memset(head, - 1, sizeof(head));
            top = 0;
            for(int i = 0; i < n; i ++)
            {
                cin >> a[a[i].id = i].h;
                if(i)
                    addEdge(i, i - 1, - 1);
            }
            sort(a, a + n);
            for(int i = 1; i < n; i ++)
            {
                int u = a[i - 1].id, v = a[i].id;
                if(u > v)
                    swap(u, v);
                addEdge(u, v, d);
            }
            int L = 0, R = 1, s = a[0].id, t = a[n - 1].id;
            if(s > t)
                swap(s, t);
            Q[L] = s;
            memset(dis, 127, sizeof(dis));
            dis[s] = 0;
            memset(inQ, 0, sizeof(inQ));
            inQ[s] = 1;
            memset(vis, 0, sizeof(vis));
            vis[s] = 1;
            int flag = 0;
            while(L < R)
            {
                int u = Q[L];
                for(int i = head[u]; i != - 1; i = G[i].next)
                {
                    int v = G[i].v;
                    if(dis[u] + G[i].w >= dis[v])
                        continue;
                    dis[v] = dis[u] + G[i].w;
                    if(! inQ[v])
                    {
                        inQ[v] = 1;
                        Q[R ++] = v;
                        vis[v] ++;
                        if(vis[v] > n)
                        {
                            flag = 1;
                            break;
                        }
                    }
                }
                inQ[u] = 0;
                L ++;
            }
            if(flag)
                printf("Case %d: -1
    ", ++ _case);
            else
                printf("Case %d: %d
    ", ++ _case, abs(dis[t]));
        }
    }
  • 相关阅读:
    公用表表达式(CTE)的递归调用
    c# 如何让tooltip显示文字换行
    实战 SQL Server 2008 数据库误删除数据的恢复
    SQL SERVER数据库中 是否可以对视图进行修改删除
    asp.net中实现文件批量上传
    sql server 2008学习2 文件和文件组
    sql server 2008学习3 表组织和索引组织
    sql server 2008学习4 设计索引的建议
    sql server 2008学习10 存储过程
    .net 调用 sql server 自定义函数,并输出返回值
  • 原文地址:https://www.cnblogs.com/ZeonfaiHo/p/6402843.html
Copyright © 2011-2022 走看看