poj2706 connect

唉  这题。。 线段相交判断+DFS

最终结果的判定就是看有没有赢家,不管谁赢都行;

而且可能给的m步棋没走完,但胜负已分;

只要把m步的能连的边都连起来(先到先连,相同颜色的线也不能相交),然后根据端点是否相等进行DFS,看能不能搜到另一端就好了

偷了几组数据
Sample Input
4 5
0 2 2 4 4 2 3 2 2 3
 
4 5
0 2 2 4 4 2 3 2 2 1
 
7 11
0 3 6 5 3 2 5 7 7 2 4 4 5 3 5 2 4 5 4 0 2 4
 
5 9
3 1 3 3 0 2 2 5 2 3 2 1 4 3 4 0 5 1
 
4 5
0 1 2 0 1 3 2 2 4 1
 
8 17
2 2 2 3 2 4 2 0 3 1 1 6 3 5 4 1 5 1 4 5 5 5 6 0 6 2 6 3 6 4 1 8 4 3
 
8 21
2 2 2 3 2 4 2 0 3 1 1 6 3 5 4 1 5 1 4 5 5 5 6 0 6 2 6 3 6 4 1 8 0 1 5 8 8 5 3 7 4 3
 
8 21
2 2 2 3 2 4 2 0 3 1 1 6 3 5 4 1 5 1 4 5 5 5 6 0 6 2 6 3 6 4 1 8 0 1 5 8 8 5 4 4 4 3
 
8 21
2 2 2 3 2 4 2 0 3 1 1 6 3 5 4 1 5 1 4 5 5 5 6 0 6 2 6 3 6 4 1 8 0 1 5 8 8 3 4 4 4 3
 
8 21
2 2 2 3 2 4 2 0 3 1 1 6 3 5 4 1 5 1 4 5 5 5 6 0 6 2 6 3 6 4 1 8 0 1 5 8 8 5 3 3 4 3
 
10 99
5 4 7 9 7 3 8 7 1 8 8 10 5 5 5 3 10 7 7 10 4 1 2 2 9 5 3 5 3 9 9 8 4 8 4 2 2 1 2 4 10 4 4 0 0 7 7 0 1 1 9 7 1 7 9 10 0 1 3 7 10 1 7 1 2 3 7 7 7 2 4 5 5 1 6 0 7 4 9 3 3 6 1 4 9 1 2 5 0 9 5 10 4 4 1 3 2 6 1 2 9 9 5 8 4 3 3 10 8 6 1 10 4 7 7 8 6 7 2 10 6 6 5 9 10 6 3 0 5 2 3 3 0 5 8 2 10 5 5 0 4 6 8 8 1 9 2 0 2 9 8 5 0 3 2 8 7 6 1 6 8 1 5 7 7 5 3 4 8 3 6 4 9 6 2 7 0 6 1 0 10 8 6 8 5 6 4 10 10 2 6 1 10 3 4 9 3 1
 
20 221
0 4 8 15 15 3 3 2 1 15 8 11 1 18 6 1 6 4 12 1 16 13 19 1 9 18 5 17 15 12 6 7 19 5 14 15 12 9 6 19 16 6 13 9 3 15 15 13 19 11 9 11 20 14 2 11 12 15 18 4 19 4 12 16 17 10 17 20 2 9 6 20 0 16 19 9 8 18 11 13 14 13 13 17 4 19 14 1 14 12 10 15 6 10 12 10 2 6 17 16 19 18 12 17 13 2 14 2 18 9 17 3 20 5 14 16 7 6 5 5 15 2 6 12 8 6 16 18 1 17 9 16 14 5 8 2 7 1 15 7 15 8 2 1 4 3 1 2 15 4 10 14 10 7 12 19 1 7 3 14 6 15 15 14 11 19 12 4 17 18 6 5 10 2 17 0 9 13 1 5 0 1 13 7 5 16 8 5 9 8 16 3 3 16 18 13 11 6 3 9 8 7 10 19 8 13 15 10 7 4 12 7 8 17 4 14 7 17 11 16 0 13 16 11 6 6 16 2 2 17 8 3 16 15 1 10 2 15 4 2 9 4 12 2 19 8 15 5 14 14 16 9 16 5 9 10 3 7 2 13 7 13 6 9 3 13 10 1 15 18 14 3 2 19 5 0 4 11 7 14 12 3 13 20 17 7 16 17 12 6 18 18 18 14 5 20 12 8 16 0 15 9 5 4 2 3 8 10 20 10 14 7 14 17 8 16 4 5 19 2 10 18 11 18 6 17 11 10 3 8 10 13 13 11 1 6 10 5 7 15 5 12 14 6 7 9 10 3 8 19 8 1 11 4 7 0 13 19 7 12 19 16 17 14 3 12 5 13 12 11 3 0 18 12 3 5 3 19 6 2 0 3 17 17 7 10 13 3 4 15 17 19 20 7 8 8 7 2 10 11 18 17 11 9 15 1 19 0 16 4 13 16 5 8 11 3 20 18 16 19 19 13 18 16 14 19 5 19 15 16 17 2 2 5 9 7 16 7 14 9 0 5
 
20 221
0 4 8 15 15 3 3 2 1 15 8 11 1 18 6 1 6 4 12 1 16 13 19 1 9 18 5 17 15 12 6 7 19 5 14 15 12 9 6 19 16 6 13 9 3 15 15 13 19 11 9 11 20 14 2 11 12 15 18 4 19 4 12 16 17 10 17 20 2 9 6 20 0 16 19 9 8 18 11 13 14 13 13 17 4 19 14 1 14 12 10 15 6 10 12 10 2 6 17 16 19 18 12 17 13 2 14 2 18 9 17 3 20 5 14 16 7 6 5 5 15 2 6 12 8 6 16 18 1 17 9 16 14 5 8 2 7 1 15 7 15 8 2 1 4 3 1 2 15 4 10 14 10 7 12 19 1 7 3 14 6 15 15 14 11 19 12 4 17 18 6 5 10 2 17 0 9 13 1 5 0 1 13 7 5 16 8 5 9 8 16 3 3 16 18 13 11 6 3 9 8 7 10 19 8 13 15 10 7 4 12 7 8 17 4 14 7 17 11 16 0 13 16 11 6 6 16 2 2 17 8 3 16 15 1 10 2 15 4 2 9 4 12 2 19 8 15 5 14 14 16 9 16 5 9 10 3 7 2 13 7 13 6 9 3 13 10 1 15 18 14 3 2 19 5 0 4 11 7 14 12 3 13 20 17 7 16 17 12 6 18 18 18 14 5 20 12 8 16 0 15 9 5 4 2 3 8 10 20 10 14 7 14 17 8 16 4 5 19 2 10 18 11 18 6 17 11 10 3 8 10 13 13 11 1 6 10 5 7 15 5 12 14 6 7 9 10 3 8 19 8 1 11 4 7 0 13 19 7 12 19 16 17 14 3 12 5 13 12 11 3 0 18 12 3 5 3 19 6 2 0 3 17 17 7 10 13 3 4 15 17 19 20 7 8 8 7 2 10 11 18 17 11 9 15 1 19 0 16 4 13 16 5 8 11 3 20 18 16 19 19 13 18 16 14 19 5 19 15 16 17 2 2 5 9 7 16 7 14 9 1 14
 
10 97
5 4 7 9 7 3 8 7 1 8 8 10 5 5 5 3 10 7 7 10 4 1 2 2 9 5 3 5 3 9 9 8 4 8 4 2 2 1 2 4 10 4 4 0 0 7 7 0 1 1 9 7 1 7 9 10 0 1 3 7 10 1 7 1 2 3 7 7 7 2 4 5 5 1 6 0 7 4 9 3 3 6 1 4 9 1 2 5 0 9 5 10 4 4 1 3 2 6 1 2 9 9 5 8 4 3 3 10 8 6 1 10 4 7 7 8 6 7 2 10 6 6 5 9 10 6 3 0 5 2 3 3 0 5 8 2 10 5 5 0 4 6 8 8 1 9 2 0 2 9 8 5 0 3 2 8 7 6 1 6 8 1 5 7 7 5 3 4 8 3 6 4 9 6 2 7 0 6 1 0 10 8 6 8 5 6 4 10 10 2 6 1 10 3
10 99
5 4 7 9 7 3 8 7 1 8 8 10 5 5 5 3 10 7 7 10 4 1 2 2 9 5 3 5 3 9 9 8 4 8 4 2 2 1 2 4 10 4 4 0 0 7 7 0 1 1 9 7 1 7 9 10 0 1 3 7 10 1 7 1 2 3 7 7 7 2 4 5 5 1 6 0 7 4 9 3 3 6 1 4 9 1 2 5 0 9 5 10 4 4 1 3 2 6 1 2 9 9 5 8 4 3 3 10 8 6 1 10 4 7 7 8 6 7 2 10 6 6 5 9 10 6 3 0 5 2 3 3 0 5 8 2 10 5 5 0 4 6 8 8 1 9 2 0 2 9 8 5 0 3 2 8 7 6 1 6 8 1 5 7 7 5 3 4 8 3 6 4 9 6 2 7 0 6 1 0 10 8 6 8 5 6 4 10 10 2 6 1 10 3 4 9 1 5
 
0 0
 
Sample Output
no
yes
yes
yes
no
no
yes
no
yes
no
yes
yes
no
no
no
 


详细看代码。。有注释

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#define maxn 1000100
#define eps 1e-8

using namespace std;
typedef struct Point
{
    int x,y;
    friend bool operator == (Point a,Point b)
    {
        return (a.x==b.x && a.y==b.y);
    }
}Point;

int n,m;
struct Edge
{
    Point u,v;

}edge_b[250*250],edge_w[250*250];

int edge_num_b,edge_num_w;

int mx[]={-2,-2,+2,+2,-1,-1,+1,+1};
int my[]={-1,+1,+1,-1,-2,+2,-2,+2};

int _map[30][30];
bool vis[250*250];
bool flag_w,flag_b;

double xmult(Point p1,Point p2,Point p)
{
    return (p1.x-p.x)*(p2.y-p.y)-(p2.x-p.x)*(p1.y-p.y);
}

bool ifcross(Edge A,Edge B)
{
    return  (max(A.u.x,A.v.x) >= min(B.u.x,B.v.x) ) &&
            (max(B.u.x,B.v.x) >= min(A.u.x,A.v.x) ) &&
            (max(A.u.y,A.v.y) >= min(B.u.y,B.v.y) ) &&
            (max(B.u.y,B.v.y) >= min(A.u.y,A.v.y) ) &&
            (xmult (A.u,B.u,A.v) * xmult (A.u,A.v,B.v) > eps ) &&
            (xmult (B.u,A.u,B.v) * xmult (B.u,B.v,A.v) > eps );
}
bool cross(int x,int y,int nowx,int nowy)
{
    Edge temp ;
    temp.u.x=x;
    temp.u.y=y;
    temp.v.x=nowx;
    temp.v.y=nowy;
    int i;
    for(i=0;i<edge_num_b;++i)
    {
        if(ifcross(temp,edge_b[i]))
        {
            return true;
        }
    }
    for(i=0;i<edge_num_w;++i)
    {
        if(ifcross(temp,edge_w[i]))
            return true;
    }
    return false;
}


void add(int x,int y,int type)//1 b 0 w
{
    int i;
    for(i=0;i<8;++i)
    {
        int nowx=x+mx[i];
        int nowy=y+my[i];
        if(nowx>=0&&nowx<=n && (type==_map[nowx][nowy]) && !cross(x,y,nowx,nowy) )
        {
            if(type==1)//black
            {
                edge_b[edge_num_b].u.x=nowx;
                edge_b[edge_num_b].u.y=nowy;
                edge_b[edge_num_b].v.x=x;
                edge_b[edge_num_b].v.y=y;
                edge_num_b++;
            }
            else
            {

                edge_w[edge_num_w].u.x=nowx;
                edge_w[edge_num_w].u.y=nowy;
                edge_w[edge_num_w].v.x=x;
                edge_w[edge_num_w].v.y=y;
                edge_num_w++;
            }
        }
    }
    return;
}


void dfs_w(Edge temp)
{
    if(flag_w)
        return;
//    if(temp.v.y==n)//错误
    if(temp.v.y==n || temp.u.y==n)//不分方向 能连就行
    {
        flag_w=1;
        return;
    }
    int i;
    for(i=0;i<edge_num_w;++i)
    {
//        if(!vis[i]&&( (edge_w[i].u==temp.v) ))
        if(!vis[i]&&( (edge_w[i].u==temp.v) || (edge_w[i].u==temp.u) || (edge_w[i].v==temp.v) || (edge_w[i].v==temp.u)))//不分方向 能连就行
        {
            vis[i]=1;
            dfs_w(edge_w[i]);
//            vis[i]=0;//能走的都走完了 不用撤销标记
        }
    }
}

void dfs_b(Edge temp)
{
    if(flag_b)
        return;
//    if(temp.v.x==n)
    if(temp.v.x==n || temp.u.x==n)//不分方向 能连就行
    {
        flag_b=1;
        return;
    }
    int i;
    for(i=0;i<edge_num_b;++i)
    {
//        if(!vis[i]&& edge_b[i].u==temp.v)
        if(!vis[i]&&( (edge_b[i].u==temp.v) || (edge_b[i].u==temp.u) || (edge_b[i].v==temp.v) || (edge_b[i].v==temp.u)))//不分方向 能连就行

        {
            vis[i]=1;
            dfs_b(edge_b[i]);
//            vis[i]=0;
        }
    }
}
int main()
{

    while(scanf("%d%d",&n,&m), n||m )
    {
        int i;
        edge_num_w=0;
        edge_num_b=0;
        memset(_map,-1,sizeof(_map));
        int x,y;
        for(i=1;i<=m;++i)
        {
            scanf("%d%d",&x,&y);
            if(i&1){//b
                _map[x][y]=1;
                add(x,y,1);
            }
            else{
                _map[x][y]=0;
                add(x,y,0);
            }
        }
        flag_w=0;
        memset(vis,false,sizeof(vis));
        for(i=0;i<edge_num_w;++i)
        {
//            if(edge_w[i].u.y==0)
            if(edge_w[i].u.y==0||edge_w[i].v.y==0)//不分方向 能连就行
            {
                vis[i]=1;
                dfs_w(edge_w[i]);
                vis[i]=0;
            }
        }

        flag_b=0;
        memset(vis,false,sizeof(vis));
        for(i=0;i<edge_num_b;++i)
        {
//            if(edge_b[i].u.x==0)
            if(edge_b[i].u.x==0||edge_b[i].v.x==0)
            {
                vis[i]=1;
                dfs_b(edge_b[i]);
                vis[i]=0;
            }
        }
//        cout<<flag_w<<flag_b<<endl;
        if( (flag_b ) || (flag_w ) )
        {
            printf("yes\n");
        }
        else
        {
            printf("no\n");
        }

    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值