HDU 5652 二分加搜索 http://acm.split.hdu.edu.cn/showproblem.php?pid=5652

Problem Description

A long time ago there are no himalayas between India and China, the both cultures are frequently exchanged and are kept in sync at that time, but eventually himalayas rise up. With that at first the communation started to reduce and eventually died.

Let‘s assume from my crude drawing that the only way to reaching from India to China or viceversa is through that grid, blue portion is the ocean and people haven‘t yet invented the ship. and the yellow portion is desert and has ghosts roaming around so people can‘t travel that way. and the black portions are the location which have mountains and white portions are plateau which are suitable for travelling. moutains are very big to get to the top, height of these mountains is infinite. So if there is mountain between two white portions you can‘t travel by climbing the mountain.
And at each step people can go to 4 adjacent positions.

Our archeologists have taken sample of each mountain and estimated at which point they rise up at that place. So given the times at which each mountains rised up you have to tell at which time the communication between India and China got completely cut off.

Input

There are multi test cases. the first line is a sinle integer T which represents the number of test cases.

For each test case, the first line contains two space seperated integers N,M. next N lines consists of strings composed of 0,1 characters. 1 denoting that there‘s already a mountain at that place, 0 denoting the plateau. on N+2 line there will be an integer Q denoting the number of mountains that rised up in the order of times. Next Q lines contain 2 space seperated integers X,Y denoting that at ith year a mountain rised up at location X,Y.

T≤10

1≤N≤500

1≤M≤500

1≤Q≤N∗M

0≤X<N

0≤Y<M

Output

Single line at which year the communication got cut off.

print -1 if these two countries still connected in the end.

Hint:

From the picture above, we can see that China and India have no communication since 4th year.

Sample Input

1
4 6
011010
000010
100001
001000
7
0 3
1 5
1 3
0 0
1 2
2 4
2 1

Sample Output

4

在hdu上提交的  一直wa  以为是过程有问题   最后发现数组开小了  一改就对了  自我感觉这是一道比较水的题  主要和二分挂钩    下面广搜来一波

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<math.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define N 506
char str[N][N];
int w[N][N],aa[N*N],b[N*N],d,n,m;
int a[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};
struct node
{
    int x,y;
};
int qq(int x,int y)
{
    memset(w,0,sizeof(w));
    queue<node> Q;
    node q,p;
    q.x=x;
    q.y=y;
    Q.push(q);
    w[x][y]=1;
    while(Q.size())
    {
        p=Q.front();
        Q.pop();
        if(p.x==n-1)///表示可以到底
            return 1;
        for(int i=0; i<4; i++)
        {
            q.x=p.x+a[i][0];
            q.y=p.y+a[i][1];
            int e=q.x,f=q.y;
            if(e>=0&&e<n&&f>=0&&f<m&&!w[e][f]&&str[e][f]==‘0‘)
            {
                w[e][f]=1;
                Q.push(q);
            }
        }
    }
    return 0;///无到底的点
}
void qqq(int x)
{
    for(int i=1; i<=x; i++)
        str[aa[i]][b[i]]=‘0‘;
}
int q(int x)
{
    for(int i=1; i<=x; i++)
        str[aa[i]][b[i]]=‘1‘;
    for(int j=0; j<m; j++)
        if(str[0][j]==‘0‘)
        {
            if(qq(0,j))///如果已经存在到底的点  则返回0  结束
                return 0;
        }
    return 1;
}
int main()
{
    int T,t;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0; i<n; i++)
            scanf("%s",str[i]);
        scanf("%d",&t);
        for(int i=1; i<=t; i++)
            scanf("%d%d",&aa[i],&b[i]);
        int l=1,r=t,mid,ans=-1;
        while(l<=r)
        {
            mid=(l+r)/2;
            if(q(mid))///如果已经不满足  ans提取出来   继续减少范围
            {
                ans=mid;
                r=mid-1;
            }
            else
                l=mid+1;
            qqq(mid);///因为你改变了一部分数  就重新改变过来
        }
        printf("%d\n",ans);
    }
    return 0;
}

深搜也可以的

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<math.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define N 506
char str[N][N];
int w[N][N],aa[N],b[N],d,n,m;
int a[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};
void qq(int x,int y)
{
    if(d==1)
        return ;
    for(int i=0; i<4; i++)
    {
        int e=x+a[i][0];
        int f=y+a[i][1];
        if(e==n-1&&str[e][f]==‘0‘)
        {
            d=1;
            return ;
        }
        if(e>=0&&e<n&&f>=0&&f<m&&!w[e][f]&&str[e][f]==‘0‘)
        {
            w[e][f]=1;
            qq(e,f);
        }
    }
    return ;
}
void qqq(int x)
{
    for(int i=1; i<=x; i++)
        str[aa[i]][b[i]]=‘0‘;
}
int q(int x)
{
    for(int i=1; i<=x; i++)
        str[aa[i]][b[i]]=‘1‘;
    for(int j=0; j<m; j++)
        if(str[0][j]==‘0‘)
        {
            d=0;
            memset(w,0,sizeof(w));
            qq(0,j);
            if(d==1)
                return 0;
        }
    return 1;
}
int main()
{
    int T,t;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0; i<n; i++)
            scanf("%s",str[i]);
        scanf("%d",&t);
        for(int i=1; i<=t; i++)
            scanf("%d%d",&aa[i],&b[i]);
        int l=1,r=t,mid,ans=-1;
        while(l<=r)
        {
            mid=(l+r)/2;
            if(q(mid))
            {
                ans=mid;
                r=mid-1;
            }
            else
                l=mid+1;
            qqq(mid);
        }
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-12 08:18:25

HDU 5652 二分加搜索 http://acm.split.hdu.edu.cn/showproblem.php?pid=5652的相关文章

HDU 5547 4*4数独 http://acm.split.hdu.edu.cn/status.php

Sample Input 3 **** 2341 4123 3214 *243 *312 *421 *134 *41* **3* 2*41 4*2* Sample Output Case #1: 1432 2341 4123 3214 Case #2: 1243 4312 3421 2134 Case #3: 3412 1234 2341 4123 #include<iostream> #include<cstdio> #include<cstring> #includ

HDU 1285 确定比赛名次 http://acm.split.hdu.edu.cn/showproblem.php?pid=1285

Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前.现在请你编程序确定排名. Input 输入有若干组,每组中的第一行为二个数N(1<=N<=500),M:其中N表示队伍的个数,M表示接着有M行的输入数据.接下来的M行数据中,每行也有两个整数P1,P2表示

hdu 4004 (二分加贪心) 青蛙过河

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4004 题目意思是青蛙要过河,现在给你河的宽度,河中石头的个数(青蛙要从石头上跳过河,这些石头都是在垂直于河岸的一条直线上) 还有青蛙能够跳跃的 最多 的次数,还有每个石头离河岸的距离,问的是青蛙一步最少要跳多少米可以过河> 这是一道二分加贪心的题,从0到的河宽度开始二分,二分出一个数然后判断在这样的最小步数(一步跳多少距离)下能否过河 判断的时候要贪心 主要难在思维上,关键是要想到二分上去,能想到

HDU 4911 http://acm.hdu.edu.cn/showproblem.php?pid=4911(线段树求逆序对)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4911 解题报告: 给出一个长度为n的序列,然后给出一个k,要你求最多做k次相邻的数字交换后,逆序数最少是多少? 因为每次相邻的交换操作最多只能减少一个逆序对,所以最多可以减少k个逆序对,所以我们只要求出原来的序列有多少个逆序对然后减去k再跟0取较大的就可以了. 因为数据范围是10的五次方,所以暴力求肯定会TLE,所以要用n*logn算法求逆序对,n*logn算法有几种可以求逆序对的: 线段树,树状数

HDU-4632 http://acm.hdu.edu.cn/showproblem.php?pid=4632

http://acm.hdu.edu.cn/showproblem.php?pid=4632 题意: 一个字符串,有多少个subsequence是回文串. 别人的题解: 用dp[i][j]表示这一段里有多少个回文串,那首先dp[i][j]=dp[i+1][j]+dp[i][j-1],但是dp[i+1][j]和dp[i][j-1]可能有公共部分,所以要减去dp[i+1][j-1]. 如果str[i]==str[j]的话,还要加上dp[i+1][j-1]+1. 但是自己却是这样想的,把每个区间都要看

http://acm.hdu.edu.cn/showproblem.php?pid=2825

地址:http://acm.hdu.edu.cn/showproblem.php?pid=2825 题目: Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6862    Accepted Submission(s): 2279 Problem Description Liyuan lives in a

http://acm.split.hdu.edu.cn/showproblem.php?pid=2255

Problem Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子.这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子.另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比如有3间房子,一家老百姓可以对第一间出10

http://acm.hdu.edu.cn/showproblem.php?pid=2579

#include<stdio.h> #include<string.h> #include<queue> #define N 110 int m, n, k, x1, x2, y1, y2; char map[N][N]; int v[N][N][N];//当时间是k的倍数时,障碍消失,之后又重现,所以在平时使用的二维标记数组中再加一维 int d[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; using namespace s

字符串处理 最佳裁判http://acm.hdu.edu.cn/showproblem.php?pid=4520

#include <stdio.h> int main() { int N; scanf("%d",&N);//先输入 double a[N],b[N],c,d=0,o[N-1],e,f;//这里定义3个数组下面会用到 for (int i=0; i<N; i++) { scanf("%lf",&a[i]); b[i]=a[i];//得到2个一样的数组,因为有一个数组因为排序要改变 } for (int i=0; i<N-1;