poj--2706--Connect(极限大模拟)

Connect

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 1148   Accepted: 375

Description

Figure 1 Figure 2 Figure 3a Figure 3b Figure 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

Source

Mid-Central USA 2005

黑白棋的游戏,在n*n的棋盘上,黑棋先手,且最后一步是黑棋。当黑棋从x=0连接的到x=n,时黑棋获胜,问最后一步是不是致胜的一步

每个点都可以和它周围的八个点连接,类似象棋中的马,但是在连接两个点的时候,在连线之间不能有其他的连线(包括黑棋自身的连线)。所以在连接一条线的时候,要判断其他的可能会切割这条线的九条线是否存在。

先判断不包含最后一步的黑棋能不能胜利,再判断加上最后一步后能不能获胜,如果开始不能获胜,后来获胜,那么输出yes,否则,输出no

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std ;
int vis[500] ;
int Map[25][25] , c[500][500] ;//ºÚΪ1£¬°×Ϊ-1
queue <int> que ;
void solve1(int i,int j,int n,int temp)
{
    if( (i-1) >= 0 && (i+1) < n && (j-1) >= 0 && c[ (i-1)*n+j ][ (i+1)*n+(j-1) ] != 0 )
        return ;
    if( (i-1) >= 0 && (j-2) >= 0 && (i+1) < n && (j-1) >= 0 && c[ (i-1)*n+(j-2) ][ (i+1)*n+(j-1) ] != 0 )
        return ;
    if( (j-3) >= 0 && (i+1) < n && (j-1) >= 0 && c[ i*n+(j-3) ][ (i+1)*n+(j-1) ] != 0 )
        return ;
    if( (j-1) >= 0 && (i+1) < n && (j+1) < n && c[ i*n+(j-1) ][ (i+1)*n+(j+1) ] != 0 )
        return ;
    if( (j-1) >= 0 && (i+2) < n && c[ i*n+(j-1) ][ (i+2)*n+j ] != 0 )
        return ;
    if( (j-1) >= 0 && (i+2) < n && (j-2) >= 0 && c[ i*n+(j-1) ][ (i+2)*n+(j-2) ] != 0 )
        return ;
    if( (i-1) >= 0 && (j-1) >= 0 && (i+1) < n && c[ (i-1)*n+(j-1) ][ (i+1)*n+j ] != 0 )
        return ;
    if( (i+1) < n && (j-2) >= 0 && c[ (i+1)*n+j ][ i*n+(j-2) ] != 0 )
        return ;
    if( (j-2) >= 0 && (i+2) < n && (j-1) >= 0 && c[ i*n+(j-2) ][ (i+2)*n+(j-1) ] != 0 )
        return ;
    c[ i*n+j ][ (i+1)*n+(j-2) ] = c[ (i+1)*n+(j-2) ][ i*n+j ] = temp ;
    return ;
}
void solve2(int u,int v,int n,int temp)
{
    if( (u-1) >= 0 && (v-1) >= 0 )
    {
        if( (u+1) < n && c[ (u-1)*n+(v-1) ][ (u+1)*n+v ] != 0 ) return ;
        if( (u+1) < n && (v-2) >= 0 && c[ (u-1)*n+(v-1) ][ (u+1)*n+(v-2) ] != 0 ) return ;
        if( (v-3) >= 0 && c[ (u-1)*n+(v-1) ][ u*n+(v-3) ] != 0 ) return ;
    }
    if( (v-1) >= 0 )
    {
        if( (u-1) >= 0 && (v+1) < n && c[ u*n+(v-1) ][ (u-1)*n+(v+1) ] != 0 ) return ;
        if( (u-2) >= 0 && c[ u*n+(v-1) ][ (u-2)*n+v ] != 0 ) return ;
        if( (u-2) >= 0 && (v-2) >= 0 && c[ u*n+(v-1) ][ (u-2)*n+(v-2) ] != 0 ) return ;
    }
    if( (u+1) < n && (v-1) >= 0 && (u-1) >= 0 && c[ (u+1)*n+(v-1) ][ (u-1)*n+v ] != 0 ) return ;
    if( (u-1) >= 0 && (v-2) >= 0 && c[ (u-1)*n+v ][ u*n+(v-2) ] != 0 ) return ;
    if( (v-2) >= 0 && (u-2) >= 0 && (v-1) >= 0 && c[ u*n+(v-2) ][ (u-2)*n+(v-1) ] != 0 ) return ;
    c[ u*n+v ][ (u-1)*n+(v-2) ] = c[ (u-1)*n+(v-2) ][ u*n+v ] = temp ;
    return ;
}
void solve3(int u,int v,int n,int temp)
{
    if( (u+1) < n )
    {
        if( (u-1) >= 0 && (v-1) >= 0 && c[ (u+1)*n+v ][ (u-1)*n+(v-1) ] != 0 ) return ;
        if( (v-2) >= 0 && c[ (u+1)*n+v ][ u*n+(v-2) ] != 0 ) return ;
        if( (u+2) < n && (v-2) >= 0 && c[ (u+1)*n+v ][ (u+2)*n+(v-2) ] != 0 ) return ;
    }
    if( (u+1) < n && (v-1) >= 0 )
    {
        if( (v+1) < n && c[ (u+1)*n+(v-1) ][ u*n+(v+1) ] != 0 ) return ;
        if( (u+2) < n && (v+1) < n && c[ (u+1)*n+(v-1) ][ (u+2)*n+(v+1) ] != 0 ) return ;
        if( (u+3) < n && c[ (u+1)*n+(v-1) ][ (u+3)*n+v ] != 0 ) return ;
    }
    if( (u+1) < n && (v+1) < n && (v-1) >= 0 && c[ (u+1)*n+(v+1) ][ u*n+(v-1) ] != 0 ) return ;
    if( (v-1) >= 0 && (u+2) < n && c[ u*n+(v-1) ][ (u+2)*n+v ] != 0 ) return ;
    if( (u+2) < n && (u+1) < n && (v-2) >= 0 && c[ (u+2)*n+v ][ (u+1)*n+(v-2) ] != 0 ) return ;
    c[ u*n+v ][ (u+2)*n+(v-1) ] = c[ (u+2)*n+(v-1) ][ u*n+v ] = temp ;
    return ;
}
void solve4(int u,int v,int n,int temp)
{
    if( (u-1) >= 0 )
    {
        if( (u-2) >= 0 && (v-2) >= 0 && c[ (u-1)*n+v ][ (u-2)*n+(v-2) ] != 0 ) return ;
        if( (v-2) >= 0 && c[ (u-1)*n+v ][ u*n+(v-2) ] != 0 ) return ;
        if( (u+1) < n && (v-1) >= 0 && c[ (u-1)*n+v ][ (u+1)*n+(v-1) ] != 0 ) return ;
    }
    if( (u-1) >= 0 && (v-1) >= 0 )
    {
        if( (u-3) >= 0 && c[ (u-1)*n+(v-1) ][ (v-3)*n+v ] != 0 ) return ;
        if( (u-2) >= 0 && (v+1) < n && c[ (u-1)*n+(v-1) ][ (u-2)*n+(v+1) ] != 0 ) return ;
        if( (v+1) < n && c[ (u-1)*n+(v-1) ][ u*n+(v+1) ] != 0 ) return ;
    }
    if( (u-1) >= 0 && (v+1) < n && (v-1) >= 0 && c[ (u-1)*n+(v+1) ][ u*n+(v-1) ] != 0 ) return ;
    if( (v-1) >= 0 && (u-2) >= 0 && c[ u*n+(v-1) ][ (u-2)*n+v ] != 0 ) return ;
    if( (u-2) >= 0 && (v-2) >= 0 && c[ (u-2)*n+v ][ (u-1)*n+(v-2) ] != 0 ) return ;
    c[ u*n+v ][ (u-2)*n+(v-1) ] = c[ (u-2)*n+(v-1) ][ u*n+v ] = temp ;
    return ;
}
int bfs(int u,int n)
{
    int v , i , j ;
    while( !que.empty() ) que.pop() ;
    vis[u] = 1 ;
    que.push(u) ;
    while( !que.empty() )
    {
        u = que.front() ;
        que.pop() ;
        if( u >= (n-1)*n )
            return 1 ;
        for(i = 0 ; i < n*n ; i++)
        {
            if( c[u][i] == 1 && vis[i] == 0 )
            {
                vis[i] = 1 ;
                que.push(i) ;
            }
        }
    }
    return 0 ;
}
void solve(int temp,int n)
{
    int u , v ;
    scanf("%d %d", &u, &v) ;
    Map[u][v] = temp ;
    if( (u+1) < n && (v-2) >= 0 && Map[u][v] == Map[u+1][v-2] )
        solve1(u,v,n,temp);
    if( (u-1) >= 0 && (v+2) < n && Map[u][v] == Map[u-1][v+2] )
        solve1(u-1,v+2,n,temp) ;
    if( (u-1) >= 0 && (v-2) >= 0 && Map[u][v] == Map[u-1][v-2] )
        solve2(u,v,n,temp) ;
    if( (u+1) < n && (v+2) < n && Map[u][v] == Map[u+1][v+2] )
        solve2(u+1,v+2,n,temp) ;
    if( (u+2) < n && (v-1) >= 0 && Map[u][v] == Map[u+2][v-1] )
        solve3(u,v,n,temp) ;
    if( (u-2) >= 0 && (v+1) < n && Map[u][v] == Map[u-2][v+1] )
        solve3(u-2,v+1,n,temp) ;
    if( (u-2) >= 0 && (v-1) >= 0 && Map[u][v] == Map[u-2][v-1] )
        solve4(u,v,n,temp) ;
    if( (u+2) < n && (v+1) < n && Map[u][v] == Map[u+2][v+1] )
        solve4(u+2,v+1,n,temp) ;
}
int main()
{
    int n , m , x , y , u , v , temp , i , j ;
    while( scanf("%d %d", &n, &m) != EOF )
    {
        if( m == 0 && n == 0 ) break ;
        n++ ;
        memset(Map,0,sizeof(vis)) ;
        memset(c,0,sizeof(c)) ;
        temp = 1 ;
        m-- ;
        while( m-- )
        {
            solve(temp,n) ;
            temp = -temp ;
        }
        int k1 = 0 , k2 = 0 ;
        memset(vis,0,sizeof(vis)) ;
        for(j = 0 ; j < n ; j++)
        {
            if(  Map[0][j] == 1 && vis[j] == 0 )
            {
                k1 = bfs(j,n) ;
                if( k1 == 1 ) break ;
            }
        }
        solve(temp,n) ;
        memset(vis,0,sizeof(vis)) ;
        for(j = 0 ; j < n ; j++)
        {
            if(  Map[0][j] == 1 && vis[j] == 0 )
            {
                k2 = bfs(j,n) ;
                if( k2 == 1 ) break ;
            }
        }
        if( k1 == 0 && k2 == 1)
            printf("yes\n") ;
        else
            printf("no\n") ;
    }
    return 0;
}

时间: 2024-08-08 14:39:45

poj--2706--Connect(极限大模拟)的相关文章

POJ 1835 大模拟

宇航员 #include<iostream> #include<cstdio> #include<string> #include<cstring> #define maxn 10010 using namespace std; int a[7],temp[7]; char str[10]; void solve(int str2[],int str3[]) { if(strcmp(str,"forward")==0)//方向不变 { s

POJ 3087 Shuffle&#39;m Up (模拟+map)

题目链接:http://poj.org/problem?id=3087 题目大意:已知两堆牌s1和s2的初始状态, 其牌数均为c,按给定规则能将他们相互交叉组合成一堆牌s12,再将s12的最底下的c块牌归为s1,最顶的c块牌归为s2,依此循环下去. 现在输入s1和s2的初始状态 以及 预想的最终状态s12.问s1 s2经过多少次洗牌之后,最终能达到状态s12,若永远不可能相同,则输出"-1". 解题思路:照着模拟就好了,只是判断是否永远不能达到状态s12需要用map,定义map<

AC日记——神奇的幻方 洛谷 P2615(大模拟)

题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. 之后,按如下方式从小到大依次填写每个数K(K=2,3,…,N*N): 1.若(K−1)在第一行但不在最后一列,则将K填在最后一行,(K−1)所在列的右一列: 2.若(K−1)在最后一列但不在第一行,则将K填在第一列,(K−1)所在行的上一行: 3.若(K−1)在第一行最后一列,则将K填在(K−1)

POJ 1027 The Same Game(模拟)

题目链接 题意 : 一个10×15的格子,有三种颜色的球,颜色相同且在同一片内的球叫做cluster(具体解释就是,两个球颜色相同且一个球可以通过上下左右到达另一个球,则这两个球属于同一个cluster,同时cluster含有至少两个球),每次选择cluster中包含同色球最多的进行消除,每次消除完之后,上边的要往下移填满空的地方,一列上的球移动之前与之后相对位置不变,如果有空列,右边的列往左移动,每一列相对位置不变 . 思路 : 模拟......不停的递归..... 1 ////POJ 102

POJ 3282 Ferry Loading IV(模拟,队列)

题意   汽车通过渡船过河  渡船开始在左边   输入按车辆来的顺序输入河两岸的车   渡船每次运输的汽车的总长度不能超过渡船自己本身的长度  先来的车先走   求轮船至少跨河多少次才能将所有的车辆都运完 简单模拟  建两个队列  分别装左边的车  和右边的车   算出两边各至少需要运输多少次就行了 #include<cstdio> #include<cstring> #include<queue> using namespace std; int main() { i

POJ 2424 Flo&#39;s Restaurant 模拟

Flo's Restaurant Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2923   Accepted: 916 Description Sick and tired of pushing paper in the dreary bleary-eyed world of finance, Flo ditched her desk job and built her own restaurant. In the s

URAL 1715. Another Ball Killer (大模拟)

1715. Another Ball Killer Time limit: 2.0 second Memory limit: 64 MB Contestants often wonder what jury members do during a contest. Someone thinks that they spend all the contest fixing bugs in tests. Others say that the jury members watch the conte

poj 1008:Maya Calendar(模拟题,玛雅日历转换)

Maya Calendar Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 64795   Accepted: 19978 Description During his last sabbatical, professor M. A. Ya made a surprising discovery about the old Maya calendar. From an old knotted message, profes

POJ 3087 Shuffle&#39;m Up(模拟)

Description A common pastime for poker players at a poker table is to shuffle stacks of chips. Shuffling chips is performed by starting with two stacks of poker chips, S1 and S2, each stack containing C chips. Each stack may contain chips of several