• HDU 5652 India and China Origins(二分 + DFS)


    本文链接:http://www.cnblogs.com/Ash-ly/p/5398851.html

    题意:

      中国和印度之间有一片地方,把这片地方抽象化,于是就可以看成一个N * M矩阵,其中黑色的代表高山不能走过去,白色的代表平原,可以通行,人每次可以选择往上下左右四个方向移动,但是随着时间的变化某些白色的平原会变成黑色的高山,从而变为不可通行,题目中给出一个代表地势的图,然后有 Q 次操作,第 i 次操作 代表在第 i 年 (x, y)处的平原变成了高山,即白色变为了黑色。问中国印度最早彻底断绝的时间,如果在 Q 年后还没有断绝就输出 -1;

    思路:

      对于0 - Q年份进行二分,然后利用DFS枚举起点判断连通性。如果在mid年时隔绝已经形成,那么说明答案在[lo-mid]之间,继续二分,否则说明答案在(mid,hi]之间。回溯时不用恢复原图,因为每个点只需要判断一次连通性就可以了。

    代码:

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    
    int beginX, beginY;
    int stepX[] = {0, 0, -1, 1};//每次可选的方向
    int stepY[] = {-1, 1, 0, 0};
    int date[503][503];
    int Gra[503][503];
    int flag ;
    int N, M;
    
    int check(int x, int y){//能否走到x , y点
        if(Gra[x][y] == -2 || Gra[x][y] == 1 || Gra[x][y] == -1)
            return 0;
        return 1;
    }
    
    void backtrack(int x, int y){
        if( x == N )//走到了最底下,图连通
            flag = 1;
        else{
            for(int i = 0; i <= 3; i++){
                int tx = x + stepX[i];
                int ty = y + stepY[i];
                if(check(tx, ty)){
                    Gra[tx][ty] = -2;//已经走过
                    if(flag) return;
                    backtrack(tx, ty);//回溯继续求解
                }
            }
        }
    }
    
    struct Point{
        int x;
        int y;
    }point[250007];
    
    
    int isOk(int mid){
        memcpy(Gra, date, sizeof(date));
        for(int j = 1; j <= mid; j++)
            Gra[ point[j].x ][ point[j].y ] = 1;
        for(int i = 1; i <= M; i++){
            if(Gra[1][i] != 1){
                beginY = i;
                beginX = 1;
                flag = 0;
                backtrack(1, i);
                if(flag == 1) return 0;
            }
        }
        return 1;
    }
    
    int main(){
       // freopen("in.txt","r", stdin);
        int T;
        scanf("%d",&T);
        while(T--){
            memset(date, -1,  sizeof(date));
            scanf("%d%d",&N, &M);
            for(int i = 1; i <= N; i++)
                for(int j = 1; j <= M; j++)
                    scanf("%1d",&date[i][j]);
            int Q;
            scanf("%d",&Q);
            for(int i = 1; i <= Q; i++){
                int a,b;
                scanf("%d%d",&a, &b);
                point[i].x = a + 1;
                point[i].y = b + 1;
            }
            if(isOk(Q) == 0) {printf("-1
    "); continue;}
            int lo = 0;
            int hi = Q;
            int ans = -1;
            while(lo <= hi){//二分求解YES_LEFT
                int mid = lo + (hi - lo) / 2;
                if( isOk(mid) ) hi = mid - 1;
                else lo = mid + 1;
            }
            printf("%d
    ",lo);
        }
        return 0;
    }
  • 相关阅读:
    mysql存储过程(查询数据库内表 游标循环 if判断 插入别的表内)
    Java中调用文件中所有bat脚本
    读取pdf内容分页和全部
    前向传播
    Broadcasting 维度扩张的手段
    维度变换
    Selective Indexing
    tensorflow索引和切片
    创建tensor
    c++线程中使用detach()导致的内存非法引用问题
  • 原文地址:https://www.cnblogs.com/Ash-ly/p/5398851.html
Copyright © 2020-2023  润新知