poj2706

来源:互联网 发布:软件版本号是什么 编辑:程序博客网 时间:2024/06/08 05:59

Connect
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 1359 Accepted: 452

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
YoU http://user.qzone.qq.com/289065406/blog/1308890557­

思路:

美(sang)妙(xin)至(bing)极(kuang)的模拟,但是难度不大,难点主要在于判断连线是否相交。­

这个题一定要画好了,细心才能做出来(太恶心了)

如上图放下一只棋子后,先检查其附近的8个方位是否存在同色棋子,若存在,则检查是否允许与该同色棋子连线。­

检查连线方法如下图,以30度的方位为例:­

­

如上图,当放下新棋子后,若检测到30度方位存在与其同色的棋子,则在连接蓝线之前,先检查是否已存在9条红色的线,当且仅当这9条红线都不存在时,才允许连接蓝线。­

其他7个方位也是同样做法。­


连接起来线就好说了,直接bfs看一看能不能走到最后边界就可以了。

小优的用了两次bfs,不过我也觉得数据给的应该是合法的,毕竟如果赢了那还下什么。

另外就是连线的时候,判断九条线的时候可以稍微暴力一下白色的点们的连线,如果能连线且相交自然是不能连接的,判断相交自然是用叉积。

不过这种思想是最简单的,只要画好图就行了。

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int MAXN=250+5;int n,m;int lastx,lasty;int tu[30][30];//用来给点编号bool link[MAXN][MAXN];//表示两个点之间是否连线//8个方位int xx[8]= {-1,-2,-2,-1, 1, 2,2,1};int xy[8]= { 2, 1,-1,-2,-2,-1,1,2};struct node{    int color;    int x,y;    int connet[8];    int cnt;} peg[MAXN];void linepeg(int i);//把此点和其余的点连线bool checkwin();int main(){    int i;    while(~scanf("%d%d",&n,&m))    {        if(!n&&!m)break;        memset(tu,0,sizeof(tu));        memset(link,0,sizeof(link));    for(i=1; i<=m; ++i)    {        int x,y;        scanf("%d%d",&x,&y);        tu[x][y]=i;        peg[i].color=i%2;        peg[i].x=x;        peg[i].y=y;        peg[i].cnt=0;        if(i==m)        {            lastx=x;            lasty=y;        }        linepeg(i);//连线    }    if(checkwin())puts("yes");//搜索    else puts("no");    }    return 0;}void linepeg(int i){    int color=peg[i].color;    for(int k = 0; k < 8; ++k) //查看八个方位的棋子    {        int x=peg[i].x+xx[k];        int y=peg[i].y+xy[k];        if(x>=0&&x<=n&&y>=0&&y<=n)//边界        {            if(tu[x][y]&&peg[tu[x][y]].color==color)//可以和相同的点连线            {                switch(k)                {                    //然后就是每个方位分别判断对应的九条线段就可以了,画好图很简单                case 0:                {                    if(link[ tu[x][y-2] ][ tu[x+1][y] ])                        break;                    if(y-3>=0 && link[ tu[x][y-3] ][ tu[x+1][y-1] ])                        break;                    if(y+1<=n && link[ tu[x][y-1] ][ tu[x+1][y+1] ])                        break;                    if(x-1>=0)                    {                        if(link[ tu[x-1][y-2] ][ tu[x+1][y-1] ])                            break;                        if(link[ tu[x-1][y-1] ][ tu[x+1][y] ])                            break;                        if(link[ tu[x-1][y] ][ tu[x+1][y-1] ])                            break;                    }                    if(x+2<=n)                    {                        if(link[ tu[x+2][y-2] ][ tu[x][y-1] ])                            break;                        if(link[ tu[x+2][y-1] ][ tu[x][y-2] ])                            break;                        if(link[ tu[x+2][y] ][ tu[x][y-1] ])                            break;                    }                    int a=tu[peg[i].x][peg[i].y];                    int b=tu[x][y];                    peg[a].connet[peg[a].cnt++]=b;                    peg[b].connet[peg[b].cnt++]=a;                    link[a][b]=link[b][a]=1;                    break;                }                case 1:                {                    if(link[ tu[x][y-1] ][ tu[x+2][y] ])                        break;                    if(x-1>=0 && link[ tu[x-1][y-1] ][ tu[x+1][y] ])                        break;                    if(x+3<=n && link[ tu[x+1][y-1] ][ tu[x+3][y] ])                        break;                    if(y-2>=0)                    {                        if(link[ tu[x][y-2] ][ tu[x+1][y] ])                            break;                        if(link[ tu[x+1][y-2] ][ tu[x+2][y] ])                            break;                        if(link[ tu[x+2][y-2] ][ tu[x+1][y] ])                            break;                    }                    if(y+1<=n)                    {                        if(link[ tu[x][y-1] ][ tu[x+1][y+1] ])                            break;                        if(link[ tu[x+1][y-1] ][ tu[x][y+1] ])                            break;                        if(link[ tu[x+1][y-1] ][ tu[x+2][y+1] ])                            break;                    }                    int a=tu[peg[i].x][peg[i].y];                    int b=tu[x][y];                    peg[a].connet[peg[a].cnt++]=b;                    peg[b].connet[peg[b].cnt++]=a;                    link[a][b]=link[b][a]=1;                    break;                }                case 2:                    {                        if(link[ tu[x][y+1] ][ tu[x+2][y] ])                            break;                        if(x-1>=0 && link[ tu[x-1][y+1] ][ tu[x+1][y] ])                            break;                        if(x+3<=n && link[ tu[x+1][y+1] ][ tu[x+3][y] ])                            break;                        if(y-1>=0)                        {                            if(link[ tu[x][y-1] ][ tu[x+1][y+1] ])                                break;                            if(link[ tu[x+1][y-1] ][ tu[x][y+1] ])                                break;                            if(link[ tu[x+2][y-1] ][ tu[x+1][y+1] ])                                break;                        }                        if(y+2<=n)                        {                            if(link[ tu[x+1][y] ][ tu[x][y+2] ])                                break;                            if(link[ tu[x+2][y] ][ tu[x+1][y+2] ])                                break;                            if(link[ tu[x+1][y] ][ tu[x+2][y+2] ])                                break;                        }                        int a=tu[peg[i].x][peg[i].y];                        int b=tu[x][y];                        peg[a].connet[peg[a].cnt++]=b;                        peg[b].connet[peg[b].cnt++]=a;                        link[a][b]=link[b][a]=1;                        break;                    }                case 3:                    {                        if(link[ tu[x][y+2] ][ tu[x+1][y] ])                            break;                        if(y-1>=0 && link[ tu[x+1][y-1] ][ tu[x][y+1] ])                            break;                        if(y+3<=n && link[ tu[x+1][y+1] ][ tu[x][y+3] ])                            break;                        if(x-1>=0)                        {                            if(link[ tu[x-1][y] ][ tu[x+1][y+1] ])                                break;                            if(link[ tu[x-1][y+1] ][ tu[x+1][y] ])                                break;                            if(link[ tu[x-1][y+2] ][ tu[x+1][y+1] ])                                break;                        }                        if(x+2<=n)                        {                            if(link[ tu[x][y+1] ][ tu[x+2][y] ])                                break;                            if(link[ tu[x][y+1] ][ tu[x+2][y+2] ])                                break;                            if(link[ tu[x][y+2] ][ tu[x+2][y+1] ])                                break;                        }                        int a=tu[peg[i].x][peg[i].y];                        int b=tu[x][y];                        peg[a].connet[peg[a].cnt++]=b;                        peg[b].connet[peg[b].cnt++]=a;                        link[a][b]=link[b][a]=1;                        break;                    }                case 4:                    {                        if(link[ tu[x-1][y] ][ tu[x][y+2] ])                            break;                        if(y-1>=0 && link[ tu[x-1][y-1] ][ tu[x][y+1] ])                            break;                        if(y+3<=n && link[ tu[x-1][y+1] ][ tu[x][y+3] ])                            break;                        if(x-2>=0)                        {                            if(link[ tu[x-2][y] ][ tu[x][y+1] ])                                break;                            if(link[ tu[x-2][y+1] ][ tu[x][y+2] ])                                break;                            if(link[ tu[x-2][y+2] ][ tu[x][y+1] ])                                break;                        }                        if(x+1<=n)                        {                            if(link[ tu[x][y] ][ tu[x-1][y+1] ])                                break;                            if(link[ tu[x+1][y+1] ][ tu[x-1][y] ])                                break;                            if(link[ tu[x+1][y+2] ][ tu[x-1][y+1] ])                                break;                        }                        int a=tu[peg[i].x][peg[i].y];                        int b=tu[x][y];                        peg[a].connet[peg[a].cnt++]=b;                        peg[b].connet[peg[b].cnt++]=a;                        link[a][b]=link[b][a]=1;                        break;                    }                case 5:                    {                        if(link[ tu[x-2][y] ][ tu[x][y+1] ])                            break;                        if(x-3>=0 && link[ tu[x-3][y] ][ tu[x-1][y+1] ])                            break;                        if(x+1<=n && link[ tu[x-1][y] ][ tu[x+1][y+1] ])                            break;                        if(y-1>=0)                        {                            if(link[ tu[x-2][y-1] ][ tu[x-1][y+1] ])                                break;                            if(link[ tu[x-1][y-1] ][ tu[x][y+1] ])                                break;                            if(link[ tu[x][y-1] ][ tu[x-1][y+1] ])                                break;                        }                        if(y+2<=n)                        {                            if(link[ tu[x-1][y] ][ tu[x-2][y+2] ])                                break;                            if(link[ tu[x-2][y] ][ tu[x-1][y+2] ])                                break;                            if(link[ tu[x-1][y] ][ tu[x][y+2] ])                                break;                        }                        int a=tu[peg[i].x][peg[i].y];                        int b=tu[x][y];                        peg[a].connet[peg[a].cnt++]=b;                        peg[b].connet[peg[b].cnt++]=a;                        link[a][b]=link[b][a]=1;                        break;                    }                case 6:                    {                        if(link[ tu[x-2][y] ][ tu[x][y-1] ])                            break;                        if(x-3>=0 && link[ tu[x-3][y] ][ tu[x-1][y-1] ])                            break;                        if(x+1<=n && link[ tu[x-1][y] ][ tu[x+1][y-1] ])                            break;                        if(y-2>=0)                        {                            if(link[ tu[x-2][y-2] ][ tu[x-1][y] ])                                break;                            if(link[ tu[x-1][y-2] ][ tu[x-2][y] ])                                break;                            if(link[ tu[x][y-2] ][ tu[x-1][y] ])                                break;                        }                        if(y+1<=n)                        {                            if(link[ tu[x-1][y-1] ][ tu[x-2][y+1] ])                                break;                            if(link[ tu[x][y-1] ][ tu[x-1][y+1] ])                                break;                            if(link[ tu[x-1][y-1] ][ tu[x][y+1] ])                                break;                        }                        int a=tu[peg[i].x][peg[i].y];                        int b=tu[x][y];                        peg[a].connet[peg[a].cnt++]=b;                        peg[b].connet[peg[b].cnt++]=a;                        link[a][b]=link[b][a]=1;                        break;                    }                case 7:                    {                        if(link[ tu[x][y-2] ][ tu[x-1][y] ])                            break;                        if(y-3>=0 && link[ tu[x][y-3] ][ tu[x-1][y-1] ])                            break;                        if(y+1<=n && link[ tu[x][y-1] ][ tu[x-1][y+1] ])                            break;                        if(x-2>=0)                        {                            if(link[ tu[x-2][y-2] ][ tu[x][y-1] ])                                break;                            if(link[ tu[x-2][y-1] ][ tu[x][y-2] ])                                break;                            if(link[ tu[x-2][y] ][ tu[x][y-1] ])                                break;                        }                        if(x+1<=n)                        {                            if(link[ tu[x-1][y-1] ][ tu[x+1][y-2] ])                                break;                            if(link[ tu[x-1][y-1] ][ tu[x+1][y] ])                                break;                            if(link[ tu[x-1][y] ][ tu[x+1][y-1] ])                                break;                        }                        int a=tu[peg[i].x][peg[i].y];                        int b=tu[x][y];                        peg[a].connet[peg[a].cnt++]=b;                        peg[b].connet[peg[b].cnt++]=a;                        link[a][b]=link[b][a]=1;                        break;                    }                }            }        }    }}bool checkwin(){    //搜索没什么好说的,最近队列习惯性静态,快但是内存消耗多    for(int k=0;k<=n;k++)    {        int p=tu[0][k];        if(p&&peg[p].color==1)//我们直接搜黑色就好了        {            int q[MAXN];            bool vis[MAXN]={0};            int head=0;            int tail=0;            q[tail++]=p;            vis[p]=1;            while(head<tail)            {                int k=q[head++];                if(peg[k].x==n)                    return 1;                for(int i=0;i<peg[k].cnt;i++)                {                    int x=peg[k].connet[i];                    if(!vis[x])                    {                        vis[x]=1;                        q[tail++]=x;                    }                }            }        }    }    return 0;}



0 0