poj 2706 Connect

来源:互联网 发布:windows 10 powershell 编辑:程序博客网 时间:2024/05/22 17:38
Connect
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 1349 Accepted: 444

Description

Figure 1Figure 2Figure 3aFigure 3bFigure 4
Your task is to decide if a specified sequence of moves in the board game Twixt ends with a winning move. 

In this version of the game, different board sizes may be specified. Pegs are placed on a board at integer coordinates in the range [0, N]. Players Black and White use pegs of their own color. Black always starts and then alternates with White, placing a peg at one unoccupied position (x,y). Black's endzones are where x equals 0 or N, and White's endzones are where y equals 0 or N. Neither player may place a peg in the other player's endzones. After each play the latest position is connected by a segment to every position with a peg of the same color that is a chess knight's move away (2 away in one coordinate and 1 away in the other), provided that a new segment will touch no segment already added, except at an endpoint. Play stops after a winning move, which is when a player's segments complete a connected path between the player's endzones. 

For example Figure 1 shows a board with N=4 after the moves (0,2), (2,4), and (4,2). Figure 2 adds the next move (3,2). Figure 3a shows a poor next move of Black to (2,3). Figure 3b shows an alternate move for Black to (2,1) which would win the game. 

Figure 4 shows the board with N=7 after Black wins in 11 moves: 
(0, 3), (6, 5), (3, 2), (5, 7), (7, 2), (4, 4), (5, 3), (5, 2), (4, 5), (4, 0), (2, 4). 

Input

The input contains from 1 to 20 datasets followed by a line containing only two zeroes, "0 0". The first line of each dataset contains the maximum coordinate N and the number of total moves M where 3 < N < 21, 4 < M < 250, and M is odd. The rest of the dataset contains a total of M coordinate pairs, with one or more pairs per line. All numbers on a line will be separated by a space. M being odd means that Black will always be the last player. All data will be legal. There will never be a winning move before the last move.

Output

The output contains one line for each data set: "yes" if the last move is a winning move and "no" otherwise.

Sample Input

4 50 2 2 4 4 2 3 2 2 34 50 2 2 4 4 2 3 2 2 17 110 3 6 5 3 2 5 7 7 2 4 45 3 5 2 4 5 4 0 2 40 0

Sample Output

noyesyes

Source

Mid-Central USA 2005

提示

题意:

给出n*n的矩阵(3<n<21),之后再给出m个点(4<m<250),黑子先手,白子后手,它们按照坐标顺序依次放入棋盘(矩阵)中,并且它们会以象棋中马的走法进行相互连线,如果之前的连线阻断了当前连线,那么这条线将不存在。那么黑子能否在最后一步时完成从最左端到达最右端。

思路:

输入输出都没什么问题,主要是线段判交,这条线段干脆就和其他线段直接用计算几何的线段判交就行了,只是不包括端点。

示例程序

Source CodeProblem: 2706Code Length: 3132BMemory: 604KTime: 16MSLanguage: GCCResult: Accepted#include <stdio.h>#include <string.h>struct point{    int x,y;}p[250];struct{    int color,id;}map[21][21];//棋盘各个棋子的编号以及颜色int n,m,w[250][250],walk[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};//w数组记录连线情况int cross(struct point a,struct point b,struct point o){    return (a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x);}int judge(struct point a,struct point b,struct point c,struct point d){    return cross(a,c,b)*cross(a,b,d)>0&&cross(c,a,d)*cross(c,d,b)>0;}int bfs(){    int v[250],q[125],i,i1,f,top;    for(i=0;n>=i;i++)//枚举最左边的点    {        if(map[0][i].color!=1)        {            continue;        }        memset(v,0,sizeof(v));        f=0;        top=0;        q[top]=map[0][i].id;        top++;        v[q[f]]=1;        while(f<top)        {            if(p[q[f]].x==n)            {                return 1;            }            for(i1=0;m>i1;i1++)            {                if(v[i1]==0&&w[q[f]][i1]==1)                {                    q[top]=i1;                    top++;                    v[i1]=1;                }            }            f++;        }    }    return 0;}void f(int x,int y,int color){    int i,i1,i2,x1,y1,pos,pos1;    struct point a,b;    pos=map[x][y].id;    for(i=0;8>i;i++)    {        x1=x+walk[i][0];        y1=y+walk[i][1];        if(x1>=0&&y1>=0&&x1<=n&&y1<=n&&map[x1][y1].color==color)//颜色是否一样且不超边界        {            pos1=map[x1][y1].id;            a.x=x;            a.y=y;            b.x=x1;            b.y=y1;            for(i1=0;m>i1;i1++)            {                for(i2=i1+1;m>i2;i2++)                {                    if(w[i1][i2]==0)//未连线                    {                        continue;                    }                    if(judge(a,b,p[i1],p[i2])==1)//判断是否相交                    {                        break;                    }                }                if(i2!=m)                {                    break;                }            }            if(i1==m)//没有线段阻挡,连线            {                w[pos][pos1]=1;                w[pos1][pos]=1;            }        }    }}int main(){    int i,flag;    scanf("%d %d",&n,&m);    while(n!=0||m!=0)    {        flag=0;        memset(map,-1,sizeof(map));        memset(w,0,sizeof(w));        for(i=0;m>i;i++)        {            scanf("%d %d",&p[i].x,&p[i].y);            if(flag==-1)//不是最后一步就达成目标,后面的数据不做处理            {                continue;            };            map[p[i].x][p[i].y].id=i;            if(i%2==0)//黑子            {                map[p[i].x][p[i].y].color=1;                f(p[i].x,p[i].y,1);//黑子连线            }            else//白子            {                map[p[i].x][p[i].y].color=2;                f(p[i].x,p[i].y,2);//白子连线            }            if(bfs()==1)//当前状态是否能达成目标            {                if(i!=m-1)//不是最后一步的情况                {                    flag--;                }                else//最后一步的情况                {                    flag++;                }            }        }        if(flag==1)        {            printf("yes\n");        }        else        {            printf("no\n");        }        scanf("%d %d",&n,&m);    }    return 0;}

0 0
原创粉丝点击