【模拟】POJ_2706_Connect

来源:互联网 发布:php超时时间设置 编辑:程序博客网 时间:2024/04/24 19:06
#include <stdio.h>#include <string.h>#include <math.h>#include <queue>#include <algorithm>using namespace std;int Map[1010][1010],vis[1010],n,m;struct p{    int x,y;} a[310];int in(int i,int j)//判断是否在日字的范围内{    if((fabs(a[i].x-a[j].x)==2&&fabs(a[i].y-a[j].y)==1)            ||(fabs(a[i].x-a[j].x)==1&&fabs(a[i].y-a[j].y)==2))        return 1;    return 0;}int multi(p A,p B,p C)//AC*AB{    return (C.x-A.x)*(B.y-A.y)-(C.y-A.y)*(B.x-A.x);}int cross(p A,p B,p C,p D)//判断两线段相交//AB CD{    if(min(A.x,B.x)<max(C.x,D.x)&&            min(A.y,B.y)<max(C.y,D.y)&&            min(C.x,D.x)<max(A.x,B.x)&&            min(C.y,D.y)<max(A.y,B.y))//跨立实验    {        if(multi(A,B,C)*multi(A,B,D)<0)//快速排斥            return 1;    }    return 0;}int judge(int x,int y)//判断这两点能不能连接{    for(int i=0; i<x; i++)    {        for(int j=0; j<x; j++)        {            if(x%2==0)            {//本来没算己方的线。。己方以前的棋子组成的线也要分隔开,不能通过                if(i%2!=0&&j%2!=0&&Map[i][j]==1&&cross(a[x],a[y],a[i],a[j]))                    return 0;                if(i%2==0&&j%2==0&&Map[i][j]==1&&cross(a[x],a[y],a[i],a[j]))                    return 0;            }            else            {                if(i%2!=0&&j%2!=0&&Map[i][j]==1&&cross(a[x],a[y],a[i],a[j]))                    return 0;                if(i%2==0&&j%2==0&&Map[i][j]==1&&cross(a[x],a[y],a[i],a[j]))                    return 0;            }        }    }    return 1;}int bfs(int index)//搜索能不能到达终点{    memset(vis,0,sizeof(vis));    queue<int>q;    q.push(index);    vis[index]=1;    while(!q.empty())    {        int t=q.front();        //printf("n = %d (%d,%d)\n",n,a[t].x,a[t].y);        if(a[t].x==n)            return 1;        for(int i=0; i<m; i++)        {            if(Map[t][i]==1&&!vis[i])            {                q.push(i);                vis[i]=1;            }        }        q.pop();    }    return 0;}int main(){    while(~scanf("%d%d",&n,&m)&&!(n==0&&m==0))    {        memset(Map,0,sizeof(Map));        for(int i=0; i<m; i++)            scanf("%d%d",&a[i].x,&a[i].y);//        for(int i=0; i<m; i++)//        {//            printf("(%d,%d)\n",a[i].x,a[i].y);//        }//        printf ("*****************\n");        for(int i=0; i<m; i++)//对于每个点        {            for(int j=0; j<i; j++)//找在它之前出现过的点            {                if(i%2==0&&j%2==0)//同是黑色                {                    if(in(i,j)&&judge(i,j))//如果再日字范围内,且a[i]与a[j]的连线没被                    {                        //白色的连线切断                        Map[i][j]=Map[j][i]=1;//连接                    }                }                else if(i%2!=0&&j%2!=0)//同是白色                {                    if(in(i,j)&&judge(i,j))                    {                        Map[i][j]=Map[j][i]=1;//连接                    }                }            }        }//建图//        for(int i=0; i<m; i++)//        {//            for(int j=0; j<m; j++)//                printf("%d ",Map[i][j]);//            printf("\n");//        }        int flag=0;//下完最后一步有没有赢        for(int i=0; i<m; i++)        {            if(a[i].x==0&&bfs(i))            {                flag=1;                break;            }        }        int flag1=0;//没下完最后一步有没有赢        for(int i=0; i<m; i++)//把跟最后一步有关的点都去掉        {            Map[m-1][i]=0;            Map[i][m-1]=0;        }        for(int i=0; i<m; i++)        {            if(a[i].x==0&&bfs(i))            {                flag1=1;                break;            }        }        //printf("flag = %d flag1 = %d\n",flag,flag1);        if(flag==1&&flag1==0)            printf("yes\n");        else  printf("no\n");    }}

0 0
原创粉丝点击