Connect(并查集+暴力判边)

5 篇文章 0 订阅
4 篇文章 0 订阅

Connect
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

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 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
0 0

Sample Output

no
yes
yes


把左右两边看做两个点

最后一步只要点LEFT和RIGHT联通,就输出yes

本题重点在如何判断线是否相交。有人用斜率写的,也可以直接暴力。

/*

因为此题不存在水平线段或者数值线段,所以可以丧心病狂的使用斜率。

设t1,t2为等待被连线的两个点,该线段所在直线斜率为k1,截距为b;

设t3,t4为有可能阻断t1,t2连线的两个点,其所在的斜率亦为k1的直线的截距为b2.b3;

若b,b2,b3满足 (b2  < b < b3)  ||  (b2  >  b > b3) 则说明t3,t4所在直线与t1,t2所在直线相交。

然此题是线段,所以还需加限制条件。

*/


一种写法:

bool checkC(int x1,int y1,int x2,int y2)//检查与(x1,y1)相连的点中有木有(x2,y2);  
{  
    for(C *p = head[x1][y1]->next;p != NULL; p = p->next)  
    {  
        if(p->x == x2 && p->y == y2)  
            return true;  
    }  
    return false;  
}  
  
bool judgeinc(int minx,int maxx,int miny,int maxy,int x,int y,int n)//检查(x,y)是否在黑线所围成的区域内  
{  
    int minx1, maxx1, miny1, maxy1;  
    minx1 = minx-1 >= 0 ? minx-1 : 0;  
    maxx1 = maxx+1 <= n ? maxx+1 : n;  
    miny1 = miny-1 >= 0 ? miny-1 : 0;  
    maxy1 = maxy+1 <= n ? maxy+1 : n;  
  
    int i,j;  
  
    for(i = minx1;i <= maxx1; ++i)  
    {  
        for(j = miny;j <= maxy; ++j)  
        {  
            if(i == x && j == y)  
                return true;  
        }  
    }  
  
  
    for(i = minx;i <= maxx; ++i)  
    {  
        for(j = miny1;j <= maxy1; ++j)  
        {  
            if(i == x && j == y)  
                return true;  
        }  
    }  
  
    return false;  
  
  
}  
  
bool judgeC(P t1,P t2,int n)//判断两点之间是否有线段阻隔  
{  
    int minx,miny,maxx,maxy;  
  
    P temp;  
  
    minx = (t1.x < t2.x ? t1.x : t2.x);  
    maxx = (t1.x > t2.x ? t1.x : t2.x);  
    miny = (t1.y < t2.y ? t1.y : t2.y);  
    maxy = (t1.y > t2.y ? t1.y : t2.y);  
  
    double k,b,b1,b2;  
    int i,j,u;  
  
    k = (t2.y-t1.y)*1.0/(t2.x-t1.x);  
    b = t2.y*1.0 - k*t2.x;  
  
    //实际上只需要检查与t1,t2在同一 ‘日’ 字内的其余四个点  
      
    for(i = minx;i <= maxx; ++i)  
    {  
        for(j = miny;j <= maxy; ++j)  
        {  
            if( !( (i == t1.x && j == t1.y) || (i == t2.x && j == t2.y) ) )  
            {  
                b1 = j*1.0 - k*i;  
  
                for(u = 0;u < 8;++u)  
                {  
                    temp.x = i+jx[u];  
                    temp.y = j+jy[u];  
  
                    if(0 <= temp.x && temp.y <= n && 0 <= temp.y && temp.y <= n)  
                    {  
                        b2 = temp.y*1.0 - k*temp.x;  
                        if( ( (b1 > b && b > b2) || (b1 < b && b < b2) ) && judgeinc(minx,maxx,miny,maxy,temp.x,temp.y,n) && checkC(i,j,temp.x,temp.y) )  
                            return false;  
                    }  
                }  
            }  
        }  
    }  
    return true;  
}  
一种写法:

void check(int fi,int x1,int y1,int li,int x2,int y2)
{
  if(x2<x1)//保证x1<x2,简化情况 
  {
  	int t=x1;x1=x2;x2=t;
  	t=y1;y1=y2;y2=t;
  }
  
  if(x1+1==x2)
  {
  	if(y1+2==y2)
  	{
  	  //1同列的情况 
	  if(v[x1+1][y1+1][x1+1][y2][0])return;
	  if(v[x1+1][y2][x1+1][y2+1][0])return;
	  if(v[x1+1][y1][x1+1][y1+1][0])return;
	  //
	  
	  if(v[x1][y1+1][x1+1][y1+1][1])return;
	  if(v[x1][y1+1][x1+1][y1+1][0])return;
	  if(v[x1+1][y1+1][x1+2][y1+1][0])return;
	  
	  if(v[x1+1][y1+2][x1+2][y1+2][1])return;
	  if(v[x1+1][y1+2][x1+2][y1+2][0])return;
	  if(v[x1][y1+2][x1+1][y1+2][0])return;
	  
	  v[x1+1][y1+1][x1+1][y1+2][1]=1;
	  v[x1+1][y1+2][x1+1][y1+1][1]=1;
	  
	  if(fi%2)
	  {
	  	fa[find(fi)]=find(li);
	  }
	  	
  	}
  	if(y1-2==y2)
  	{
  	  //0同列的情况 
  	  if(v[x1+1][y2+1][x1+1][y2+2][1])return;
	  if(v[x1+1][y2][x1+1][y2+1][1])return;
	  if(v[x1+1][y1][x1+1][y1+1][1])return;
	  //
	  
	  if(v[x1][y1][x1+1][y1][1])return;
	  if(v[x1][y1][x1+1][y1][0])return;
	  if(v[x1+1][y1][x1+2][y1][1])return;
	  
	  if(v[x1+1][y1-1][x1+2][y1-1][1])return;
	  if(v[x1+1][y1-1][x1+2][y1-1][0])return;
	  if(v[x1][y1-1][x1+1][y1-1][1])return;
	  
	  v[x1+1][y1-1][x1+1][y1][0]=1;
	  v[x1+1][y1][x1+1][y1-1][0]=1;
	  
	  if(fi%2)
	  {
	  	fa[find(fi)]=find(li);
	  }	
  	}
  }
  else if(x1+2==x2)
  {
  	if(y1+1==y2)
  	{
  	  //1
  	  if(v[x1+1][y1+1][x1+2][y1+1][0])return;
	  if(v[x1][y1+1][x1+1][y1+1][0])return;
	  if(v[x2][y1+1][x2+1][y1+1][0])return;
	  //
	  
	  if(v[x1+1][y1][x1+1][y1+1][1])return;
	  if(v[x1+1][y1][x1+1][y1+1][0])return;
	  if(v[x1+1][y1+1][x1+1][y1+2][0])return;
	  
	  if(v[x2][y2][x2][y2+1][1])return;
	  if(v[x2][y2][x2][y2+1][0])return;
	  if(v[x2][y2-1][x2][y2][0])return;
	  
	  v[x1+1][y1+1][x1+2][y1+1][1]=1;
	  v[x1+2][y1+1][x1+1][y1+1][1]=1;
	  
	  if(fi%2)
	  {
	  	fa[find(fi)]=find(li);
	  }	
  	}
  	if(y1-1==y2)
  	{
  	  //0
  	  if(v[x1+1][y2+1][x1+2][y2+1][1])return;
	  if(v[x1][y2+1][x1+1][y2+1][1])return;
	  if(v[x2][y2+1][x2+1][y2+1][1])return;
	  //
	  
	  if(v[x1+1][y1][x1+1][y1+1][1])return;
	  if(v[x1+1][y1][x1+1][y1+1][0])return;
	  if(v[x1+1][y1-1][x1+1][y1][1])return;
	  
	  if(v[x2][y2][x2][y2+1][1])return;
	  if(v[x2][y2][x2][y2+1][0])return;
	  if(v[x2][y2+1][x2][y2+2][1])return;
	  
	  v[x1+1][y1][x1+2][y1][0]=1;
	  v[x1+2][y1][x1+1][y1][0]=1;
	  
	  if(fi%2)
	  {
	  	fa[find(fi)]=find(li);
	  }	
  	}
  }
  
}

void work(int sx,int sy,int id)
{
  for(int i=1;i<id;i++)
  {
  	if(i%2==id%2)check(id,sx,sy,i,x[i],y[i]);
  }
}

一个大神感天动地的代码:

#include<iostream>
using namespace std;
 
const int size=23;
const int num=251;
int n;  //chess size
int m;  //move steps
int lastx,lasty;
int map[size][size];  //对坐标为(x,y)的棋子编号
bool link[num][num];  //标记某两个编号的棋子是否有连线
 
int posx[]={0,-1,-2,-2,-1,1,2,2,1};   //对应于(x,y)的八个方位
int posy[]={0,2,1,-1,-2,-2,-1,1,2};
 
typedef class chess
{
    public:
    int color;   //黑棋:1 白棋:0
    int r,c;
    int connet[8];  //记录与当前棋子直接相连的棋子编号
    int pc;  //connet的指针
 
    chess()
    {
        color=-1;
        pc=0;
    }
}PEG;
 
void LinePeg(PEG* peg,int i);  //把棋子peg[i]与与其相邻的八个方位的同色棋子连线
bool CheckWin(PEG* peg,bool flag);  //BFS,检查先手(黑棋)是否把终域连接在一起(赢家)
 
int main(void)
{
    while(cin>>n>>m)
    {
        if(!n && !m)
            break;
 
        memset(map,0,sizeof(map));
        memset(link,false,sizeof(link));
        PEG* peg=new PEG[m+1];
         
        for(int i=1;i<=m;i++)
        {
            int x,y;
            cin>>x>>y;
            map[x][y]=i;  //编号记录
            peg[i].r=x;
            peg[i].c=y;
 
            if(i%2)
                peg[i].color=1;  //黑棋
            else
                peg[i].color=0;  //白棋
 
            if(i==m)  //记录最后一步棋
            {
                lastx=x;
                lasty=y;
            }
 
            LinePeg(peg,i);  //把最新下的棋子与其附近的同色棋子相连
        }
        if(CheckWin(peg,true) && !CheckWin(peg,false))
            cout<<"yes"<<endl;
        else
            cout<<"no"<<endl;
    }
    return 0;
}
 
/*把棋子(x,y)与与其相邻的八个方位的同色棋子连线*/
void LinePeg(PEG* peg,int i)
{
    int color=peg[i].color;
    for(int k=1;k<=8;k++)
    {
        int r=peg[i].r+posx[k];
        int c=peg[i].c+posy[k];
         
        if(r>=0 && r<=n && c>=0 && c<=n)  //检查边界
        {
            if(map[r][c] && peg[ map[r][c] ].color==color)  //检查颜色
            {
                switch(k)  //"日"字对角连线
                {
                    case 1:  //30度方位
                    {
                        if(link[ map[r][c-2] ][ map[r+1][c] ])
                            break;
                        if(c-3>=0 && link[ map[r][c-3] ][ map[r+1][c-1] ])
                            break;
                        if(c+1<=n && link[ map[r][c-1] ][ map[r+1][c+1] ])
                            break;
                        if(r-1>=0)
                        {
                            if(link[ map[r-1][c-2] ][ map[r+1][c-1] ])
                                break;
                            if(link[ map[r-1][c-1] ][ map[r+1][c] ])
                                break;
                            if(link[ map[r-1][c] ][ map[r+1][c-1] ])
                                break;
                        }
                        if(r+2<=n)
                        {
                            if(link[ map[r+2][c-2] ][ map[r][c-1] ])
                                break;
                            if(link[ map[r+2][c-1] ][ map[r][c-2] ])
                                break;
                            if(link[ map[r+2][c] ][ map[r][c-1] ])
                                break;
                        }
 
                        int a=map[peg[i].r][peg[i].c];
                        int b=map[r][c];
                        peg[a].connet[peg[a].pc++]=b;
                        peg[b].connet[peg[b].pc++]=a;
                        link[a][b]=link[b][a]=true;
                        break;
                    }
                    case 2:  //60度方位
                    {
                        if(link[ map[r][c-1] ][ map[r+2][c] ])
                            break;
                        if(r-1>=0 && link[ map[r-1][c-1] ][ map[r+1][c] ])
                            break;
                        if(r+3<=n && link[ map[r+1][c-1] ][ map[r+3][c] ])
                            break;
                        if(c-2>=0)
                        {
                            if(link[ map[r][c-2] ][ map[r+1][c] ])
                                break;
                            if(link[ map[r+1][c-2] ][ map[r+2][c] ])
                                break;
                            if(link[ map[r+2][c-2] ][ map[r+1][c] ])
                                break;
                        }
                        if(c+1<=n)
                        {
                            if(link[ map[r][c-1] ][ map[r+1][c+1] ])
                                break;
                            if(link[ map[r+1][c-1] ][ map[r][c+1] ])
                                break;
                            if(link[ map[r+1][c-1] ][ map[r+2][c+1] ])
                                break;
                        }
 
                        int a=map[peg[i].r][peg[i].c];
                        int b=map[r][c];
                        peg[a].connet[peg[a].pc++]=b;
                        peg[b].connet[peg[b].pc++]=a;
                        link[a][b]=link[b][a]=true;
                        break;
                    }
                    case 3:  //120度方位
                    {
                        if(link[ map[r][c+1] ][ map[r+2][c] ])
                            break;
                        if(r-1>=0 && link[ map[r-1][c+1] ][ map[r+1][c] ])
                            break;
                        if(r+3<=n && link[ map[r+1][c+1] ][ map[r+3][c] ])
                            break;
                        if(c-1>=0)
                        {
                            if(link[ map[r][c-1] ][ map[r+1][c+1] ])
                                break;
                            if(link[ map[r+1][c-1] ][ map[r][c+1] ])
                                break;
                            if(link[ map[r+2][c-1] ][ map[r+1][c+1] ])
                                break;
                        }
                        if(c+2<=n)
                        {
                            if(link[ map[r+1][c] ][ map[r][c+2] ])
                                break;
                            if(link[ map[r+2][c] ][ map[r+1][c+2] ])
                                break;
                            if(link[ map[r+1][c] ][ map[r+2][c+2] ])
                                break;
                        }
 
                        int a=map[peg[i].r][peg[i].c];
                        int b=map[r][c];
                        peg[a].connet[peg[a].pc++]=b;
                        peg[b].connet[peg[b].pc++]=a;
                        link[a][b]=link[b][a]=true;
                        break;
                    }
                    case 4:  //150度方位
                    {
                        if(link[ map[r][c+2] ][ map[r+1][c] ])
                            break;
                        if(c-1>=0 && link[ map[r+1][c-1] ][ map[r][c+1] ])
                            break;
                        if(c+3<=n && link[ map[r+1][c+1] ][ map[r][c+3] ])
                            break;
                        if(r-1>=0)
                        {
                            if(link[ map[r-1][c] ][ map[r+1][c+1] ])
                                break;
                            if(link[ map[r-1][c+1] ][ map[r+1][c] ])
                                break;
                            if(link[ map[r-1][c+2] ][ map[r+1][c+1] ])
                                break;
                        }
                        if(r+2<=n)
                        {
                            if(link[ map[r][c+1] ][ map[r+2][c] ])
                                break;
                            if(link[ map[r][c+1] ][ map[r+2][c+2] ])
                                break;
                            if(link[ map[r][c+2] ][ map[r+2][c+1] ])
                                break;
                        }
 
                        int a=map[peg[i].r][peg[i].c];
                        int b=map[r][c];
                        peg[a].connet[peg[a].pc++]=b;
                        peg[b].connet[peg[b].pc++]=a;
                        link[a][b]=link[b][a]=true;
                        break;
                    }
                    case 5:  //210度方位
                    {
                        if(link[ map[r-1][c] ][ map[r][c+2] ])
                            break;
                        if(c-1>=0 && link[ map[r-1][c-1] ][ map[r][c+1] ])
                            break;
                        if(c+3<=n && link[ map[r-1][c+1] ][ map[r][c+3] ])
                            break;
                        if(r-2>=0)
                        {
                            if(link[ map[r-2][c] ][ map[r][c+1] ])
                                break;
                            if(link[ map[r-2][c+1] ][ map[r][c+2] ])
                                break;
                            if(link[ map[r-2][c+2] ][ map[r][c+1] ])
                                break;
                        }
                        if(r+1<=n)
                        {
                            if(link[ map[r][c] ][ map[r-1][c+1] ])
                                break;
                            if(link[ map[r+1][c+1] ][ map[r-1][c] ])
                                break;
                            if(link[ map[r+1][c+2] ][ map[r-1][c+1] ])
                                break;
                        }
 
                        int a=map[peg[i].r][peg[i].c];
                        int b=map[r][c];
                        peg[a].connet[peg[a].pc++]=b;
                        peg[b].connet[peg[b].pc++]=a;
                        link[a][b]=link[b][a]=true;
                        break;
                    }
                    case 6:  //240度方位
                    {
                        if(link[ map[r-2][c] ][ map[r][c+1] ])
                            break;
                        if(r-3>=0 && link[ map[r-3][c] ][ map[r-1][c+1] ])
                            break;
                        if(r+1<=n && link[ map[r-1][c] ][ map[r+1][c+1] ])
                            break;
                        if(c-1>=0)
                        {
                            if(link[ map[r-2][c-1] ][ map[r-1][c+1] ])
                                break;
                            if(link[ map[r-1][c-1] ][ map[r][c+1] ])
                                break;
                            if(link[ map[r][c-1] ][ map[r-1][c+1] ])
                                break;
                        }
                        if(c+2<=n)
                        {
                            if(link[ map[r-1][c] ][ map[r-2][c+2] ])
                                break;
                            if(link[ map[r-2][c] ][ map[r-1][c+2] ])
                                break;
                            if(link[ map[r-1][c] ][ map[r][c+2] ])
                                break;
                        }
 
                        int a=map[peg[i].r][peg[i].c];
                        int b=map[r][c];
                        peg[a].connet[peg[a].pc++]=b;
                        peg[b].connet[peg[b].pc++]=a;
                        link[a][b]=link[b][a]=true;
                        break;
                    }
                    case 7:  //300度方位
                    {
                        if(link[ map[r-2][c] ][ map[r][c-1] ])
                            break;
                        if(r-3>=0 && link[ map[r-3][c] ][ map[r-1][c-1] ])
                            break;
                        if(r+1<=n && link[ map[r-1][c] ][ map[r+1][c-1] ])
                            break;
                         
                        if(c-2>=0)
                        {
                            if(link[ map[r-2][c-2] ][ map[r-1][c] ])
                                break;
                            if(link[ map[r-1][c-2] ][ map[r-2][c] ])
                                break;
                            if(link[ map[r][c-2] ][ map[r-1][c] ])
                                break;
                        }
                        if(c+1<=n)
                        {
                            if(link[ map[r-1][c-1] ][ map[r-2][c+1] ])
                                break;
                            if(link[ map[r][c-1] ][ map[r-1][c+1] ])
                                break;
                            if(link[ map[r-1][c-1] ][ map[r][c+1] ])
                                break;
                        }
 
                        int a=map[peg[i].r][peg[i].c];
                        int b=map[r][c];
                        peg[a].connet[peg[a].pc++]=b;
                        peg[b].connet[peg[b].pc++]=a;
                        link[a][b]=link[b][a]=true;
                        break;
                    }
                    case 8:  //330度方位
                    {
                        if(link[ map[r][c-2] ][ map[r-1][c] ])
                            break;
                        if(c-3>=0 && link[ map[r][c-3] ][ map[r-1][c-1] ])
                            break;
                        if(c+1<=n && link[ map[r][c-1] ][ map[r-1][c+1] ])
                            break;
                        if(r-2>=0)
                        {
                            if(link[ map[r-2][c-2] ][ map[r][c-1] ])
                                break;
                            if(link[ map[r-2][c-1] ][ map[r][c-2] ])
                                break;
                            if(link[ map[r-2][c] ][ map[r][c-1] ])
                                break;
                        }
                        if(r+1<=n)
                        {
                            if(link[ map[r-1][c-1] ][ map[r+1][c-2] ])
                                break;
                            if(link[ map[r-1][c-1] ][ map[r+1][c] ])
                                break;
                            if(link[ map[r-1][c] ][ map[r+1][c-1] ])
                                break;
                        }
 
                        int a=map[peg[i].r][peg[i].c];
                        int b=map[r][c];
                        peg[a].connet[peg[a].pc++]=b;
                        peg[b].connet[peg[b].pc++]=a;
                        link[a][b]=link[b][a]=true;
                        break;
                    }
                }
            }
        }
    }
    return;
}
 
/*BFS,检查先手(黑棋)是否把终域连接在一起(赢家)*/
bool CheckWin(PEG* peg,bool flag)
{
    int NUM;
    if(!flag)  //通过舍弃最后一步棋,检查最后一步棋是否为决定赢棋的一步
        NUM=map[lastx][lasty];
 
    for(int k=0;k<=n;k++)
    {
        int p=map[0][k];
        if(p && p!=NUM && peg[p].color==1)
        {
            int queue[num];
            bool vist[num]={false};
            int head=0;
            int tail=0;
            queue[tail++]=p;
            vist[p]=true;
 
            while(head<tail)
            {
                int s=queue[head++];
                if(peg[s].r==n)
                    return true;
 
                for(int i=0;i<peg[s].pc;i++)
                {
                    int x=peg[s].connet[i];
                    if(!vist[x])
                    {
                        vist[x]=true;
                        if(!flag && x==NUM)
                            continue;
                        queue[tail++]=x;
                    }
                }
            }
        }
    }
    return false;
}
代码
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
/*
	并查集维护
	暴力判边 
*/
int n,m,LEFT=0,RIGHT;
int v[25][25][25][25][2];
int x[250+10],y[250+10],fa[250+10];

int find(int x)
{
	if(x==fa[x])return x;
	return fa[x]=find(fa[x]);
}

void check(int fi,int x1,int y1,int li,int x2,int y2)
{
	if(x2<x1)//保证x1<x2,简化情况 
	{
		int t=x1;x1=x2;x2=t;
		t=y1;y1=y2;y2=t;
	}
	
	if(x1+1==x2)
	{
		if(y1+2==y2)
		{
			//1同列的情况 
			if(v[x1+1][y1+1][x1+1][y2][0])return;
			if(v[x1+1][y2][x1+1][y2+1][0])return;
			if(v[x1+1][y1][x1+1][y1+1][0])return;
			
			if(v[x1][y1+1][x1+1][y1+1][1])return;
			if(v[x1][y1+1][x1+1][y1+1][0])return;
			if(v[x1+1][y1+1][x1+2][y1+1][0])return;
			
			if(v[x1+1][y1+2][x1+2][y1+2][1])return;
			if(v[x1+1][y1+2][x1+2][y1+2][0])return;
			if(v[x1][y1+2][x1+1][y1+2][0])return;
			
			v[x1+1][y1+1][x1+1][y1+2][1]=1;
			v[x1+1][y1+2][x1+1][y1+1][1]=1;
			
			if(fi%2)	fa[find(fi)]=find(li);
			
		}
		if(y1-2==y2)
		{
			//0同列的情况 
			if(v[x1+1][y2+1][x1+1][y2+2][1])return;
			if(v[x1+1][y2][x1+1][y2+1][1])return;
			if(v[x1+1][y1][x1+1][y1+1][1])return;
			
			if(v[x1][y1][x1+1][y1][1])return;
			if(v[x1][y1][x1+1][y1][0])return;
			if(v[x1+1][y1][x1+2][y1][1])return;
			
			if(v[x1+1][y1-1][x1+2][y1-1][1])return;
			if(v[x1+1][y1-1][x1+2][y1-1][0])return;
			if(v[x1][y1-1][x1+1][y1-1][1])return;
			
			v[x1+1][y1-1][x1+1][y1][0]=1;
			v[x1+1][y1][x1+1][y1-1][0]=1;
			
			if(fi%2)	fa[find(fi)]=find(li);	
		}
	}
	else if(x1+2==x2)
	{
		if(y1+1==y2)
		{
			//1
			if(v[x1+1][y1+1][x1+2][y1+1][0])return;
			if(v[x1][y1+1][x1+1][y1+1][0])return;
			if(v[x2][y1+1][x2+1][y1+1][0])return;
			//
			
			if(v[x1+1][y1][x1+1][y1+1][1])return;
			if(v[x1+1][y1][x1+1][y1+1][0])return;
			if(v[x1+1][y1+1][x1+1][y1+2][0])return;
			
			if(v[x2][y2][x2][y2+1][1])return;
			if(v[x2][y2][x2][y2+1][0])return;
			if(v[x2][y2-1][x2][y2][0])return;
			
			v[x1+1][y1+1][x1+2][y1+1][1]=1;
			v[x1+2][y1+1][x1+1][y1+1][1]=1;
			
			if(fi%2)
				fa[find(fi)]=find(li);	
		}
		if(y1-1==y2)
		{
			//0
			if(v[x1+1][y2+1][x1+2][y2+1][1])return;
			if(v[x1][y2+1][x1+1][y2+1][1])return;
			if(v[x2][y2+1][x2+1][y2+1][1])return;
			//
			
			if(v[x1+1][y1][x1+1][y1+1][1])return;
			if(v[x1+1][y1][x1+1][y1+1][0])return;
			if(v[x1+1][y1-1][x1+1][y1][1])return;
			
			if(v[x2][y2][x2][y2+1][1])return;
			if(v[x2][y2][x2][y2+1][0])return;
			if(v[x2][y2+1][x2][y2+2][1])return;
			
			v[x1+1][y1][x1+2][y1][0]=1;
			v[x1+2][y1][x1+1][y1][0]=1;
			
			if(fi%2)
				fa[find(fi)]=find(li);	
		}
	}

}

void work(int sx,int sy,int id)
{
	for(int i=1;i<id;i++)
		if(i%2==id%2)
			check(id,sx,sy,i,x[i],y[i]);
}

int main()
{
	while(scanf("%d%d",&n,&m)==2)
	{
		if(n==0&&m==0)break;
		memset(v,0,sizeof(v));
		for(int i=1;i<=m;i++)	fa[i]=i;
		fa[LEFT]=LEFT;RIGHT=m+1;fa[RIGHT]=RIGHT;
		for(int i=1;i<=m;i++)
		{
			scanf("%d%d",&x[i],&y[i]);
			if(i%2)
			{
				if(x[i]==0)fa[find(i)]=find(LEFT);
				if(x[i]==n)fa[find(i)]=find(RIGHT);
			}
			work(x[i],y[i],i);
		}
		if(find(LEFT)==find(RIGHT))printf("yes\n");
		else printf("no\n");
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值