zoukankan      html  css  js  c++  java
  • [ZPG TEST 109] 兔子跳跃【构图】

    兔子跳跃

    (jumping.pas/c/cpp)

    【问题描述】

    兔子常常感到孤独,所以当他们决定出去走走,去见见他们的朋友,他们跳的很快。

    Iris正走在一条无限长的直线道路上。这条道路上点的编号...,-3,-2,-1,0,1,2,3,...从西到东。Iris的家是在0点上,而她想要见的朋友在点1000000001。她是兔子当然只能通过移动跳跃前行,她有两个跳跃类型:小跳和大跳。当她在点x,通过一小跳,她可以移动到点(x + 2)或(x - 2)。通过一个大跳跃,她可以移动到点(x + largeJump)或点(x - largeJump)。

    不幸的是,道路总是那么坑坑洼洼,洞的大小不一,有些还可能包含连续几个点,Iris不能跳到这些洞中。

    Iris喜欢用小跳,因为这样更加的省力。请问到达1000000001所要使用的最少的大跳跃数量。如果不能达到这一点,输出-1。

    注意,道路无限长,当然能跳到超过1000000001的点。

    【输入】

    输入文件名为jumping.in。

    有多组测试数据:
    第一行,包含一个整数Num,表示测试数据的个数。(1<=Num<=10)
    每组测试数据,
    第一行一个整数N,表示共有N个洞。1<=N<=25.
    接下来一行N*2个整数,每个洞的两个端点编号,所有端点都是严格递增顺序给出。[1 and 1,000,000,000]。

    最后一个整数largeJump[3 and 1,000,000,000]。

    【输出】

    输出文件jumping.out共Num行,
    到达目标所需最少大跳跃的次数。无法到达输出-1

    【输出输出样例】

    jumping.in

    jumping.out

    5

    1

    1 2

    3

    1

    1 2

    4

    1

    2 3

    3

    4

    2 17 21 36 40 55 59 74

    19

    12

    187640193 187640493 187640738 187640845 564588641 564588679

      564588696 564588907 605671187 605671278 605671288 605671386

      755723729 755723774 755723880 755723920 795077469 795077625

      795077851 795078039 945654724 945654815 945655107 945655323

    475

    1

    -1

    3

    5

    9

    【说明】

    第一组样例中

    0 => 3 -> 5 -> 7 -> ... -> 999999999 -> 1000000001

    从0到3使用了一次大跳跃。

    第二组样例中,她只能跳到偶数的位置,不可能到达目标。

    第三组样例中,0 -> -2 => 1 => 4 => 7 -> 9 -> 11 -> ... -> 999999999 -> 1000000001 

    乍一看以为是需要离散化的dp,可是这里的大跳跃步数不是定值,所以难以做到。

    这一题其实可以构建图论模型!注意到小跳跃是没有代价的,而且小跳跃之后所在节点奇偶性不变。由于每个洞是不能进入的,所以可以把每段可以走的路作为节点,再把这个节点拆成两个点,其中一个表示这段能走的路的奇数点,另一个表示偶数点。然后枚举每对节点,如果可以从i节点大跳跃到j节点,则连边。最后求一次最短路就ok!由于是不加权的图,用bfs就可以了。

    #include <cstdio>
    #include <cstring>
    
    const int des = 1000000001;
    
    int T, n, lj, x[30], y[30], TT, tx1, ty1, tx2, ty2, lasty, idx;
    int que[60], head_, tail, h, stp[60];
    struct graph {
    	int head[60], to[3600], next[3600], lb;
    	void clear(void) {
    		memset(head, -1, sizeof head);
    		memset(next, -1, sizeof next);
    		lb = 0;
    	}
    	void ist(int aa, int ss) {
    		to[lb] = ss;
    		next[lb] = head[aa];
    		head[aa] = lb;
    		++lb;
    	}
    } g;
    
    int main(void) {
    	freopen("jumping.in", "r", stdin);
    	freopen("jumping.out", "w", stdout);
    	scanf("%d", &TT);
    	while (TT--) {
    		memset(x, 0, sizeof x);
    		memset(y, 0, sizeof y);
    		memset(que, 0, sizeof que);
    		memset(stp, -1, sizeof stp);
    		head_ = tail = 0;
    		scanf("%d", &n);
    		lasty = -2147483637;
    		idx = 0;
    		for (int i = 0; i < n; ++i) {
    			scanf("%d%d", &tx1, &ty1);
    			if (tx1 != lasty + 1) {
    				x[idx] = lasty + 1;
    				y[idx] = tx1 - 1;
    				++idx;
    			}
    			lasty = ty1;
    		}
    		x[idx] = lasty + 1;
    		y[idx] = 2147483637;
    		T = idx << 1 | 1;
    		++idx;
    		scanf("%d", &lj);
    		if (lj & 1 ^ 1) {
    			puts("-1");
    			continue;
    		}
    		g.clear();
    		for (int i = 0; i < (idx << 1); i += 2) {
    			tx1 = x[i >> 1] + (x[i >> 1] & 1? 1: 0);
    			ty1 = y[i >> 1] - (y[i >> 1] & 1? 1: 0);
    			for (int j = 1; j < (idx << 1); j += 2) {
    				tx2 = x[j >> 1] + (x[j >> 1] & 1? 0: 1);
    				ty2 = y[j >> 1] - (y[j >> 1] & 1? 0: 1);
    				if (tx1 + lj <= ty2 && ty1 + lj >= tx2 || tx1 - lj <= ty2 && ty1 - lj >= tx2) {
    					g.ist(i, j);
    				}
    			}
    		}
    		for (int i = 1; i < (idx << 1); i += 2) {
    			tx1 = x[i >> 1] + (x[i >> 1] & 1? 0: 1);
    			ty1 = y[i >> 1] - (y[i >> 1] & 1? 0: 1);
    			for (int j = 0; j < (idx << 1); j += 2) {
    				tx2 = x[j >> 1] + (x[j >> 1] & 1? 1: 0);
    				ty2 = y[j >> 1] - (y[j >> 1] & 1? 1: 0);
    				if (tx1 + lj <= ty2 && ty1 + lj >= tx2 || tx1 - lj <= ty2 && ty1 - lj >= tx2) {
    					g.ist(i, j);
    				}
    			}
    		}
    		
    		que[tail++] = 0;
    		stp[0] = 0;
    		while (head_ != tail) {
    			h = que[head_++];
    			for (int j = g.head[h]; j != -1; j = g.next[j]) {
    				if (stp[g.to[j]] == -1) {
    					stp[g.to[j]] = stp[h] + 1;
    					que[tail++] = g.to[j];
    				}
    			}
    		}
    		printf("%d
    ", stp[T]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    docker 容器管理常用命令
    第一章 入门示例
    rsyslog 日志服务器端配置
    如何利用一个按钮绑定两个事件
    select下拉框有了空行怎么办
    如何设置select下拉禁止选择
    mysql utf8 中文
    数据化决策的魅力
    数据化决策的魅力
    minor.major version 详解
  • 原文地址:https://www.cnblogs.com/ciao-sora/p/6002862.html
Copyright © 2011-2022 走看看