ZOJ 2610 Puzzle 模拟


大模拟:枚举6个方向,检查每个0能否移动


Puzzle

Time Limit: 2 Seconds       Memory Limit: 65536 KB

Little Georgie likes puzzles very much. Recently he has found a wooden triangle in the box with old toys. The side of the triangle is n inches long. The triangle is divided into n2unit triangles with lines drawn on his surface.

The interesting fact about that triangle is that it is not solid - it consists of two parts. Each of the parts is a connected set of unit triangles. Georgie has put his triangle onto the table and now wonders whether he can separate the parts. He wants to separate them without taking any part of the triangle off the table, just moving the parts by the table surface. The triangle has a small but non-zero thickness, so while being moved the parts must not intersect.

For example, if the triangle is divided into parts as it is shown on the top picture below, Georgie can separate the parts the way he wants. However in the case displayed on the bottom picture, he cannot separate the parts without lifting one of them.

Help Georgie to determine whether he can separate the parts moving them by the surface of the table.

<img src="http://acm.zju.edu.cn/onlinejudge/showImage.do?name=0000%2F2610%2Fg.gif" <="" img=""><img src="http://acm.zju.edu.cn/onlinejudge/showImage.do?name=0000%2F2610%2Fg2.gif" <="" img="">
Two puzzles corresponding the samples

Input

Input file contains one or more testcases. The first line of each testcase contains n (2 <= n <= 50). Next n lines contain the description of the triangle, i-th of these lines contains 2i - 1 characters, describing unit triangles in the i-th row, from left to right. Character '0' means that the triangle belongs to the first part of the main triangle, '1' means that it belongs to the second one.

Testcase with n = 0 designates the end of the test data, this testcase must not be processed. There is no blank line in the input file.


Output

For each puzzle output the line with its number followed by the line that states whether the parts can be separated. Do not output any blank lines.


Sample Input

6
0
001
00011
0000011
000111111
00111111111
6
0
001
00111
0011011
000000111
00111111111
0

Sample Output

Puzzle 1
Parts can be separated
Puzzle 2
Parts cannot be separated


Author:  Andrew Stankevich
Source:  Andrew Stankevich's Contest #7


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

int n;
int tu[55][200];

bool inmap(int x,int y)
{
    if((x>=1&&x<=n)&&(y>=1&&y<=2*x-1)) return true;
    return false;
}

bool check_down(int x,int y,int c,int kind)
{
    if(kind==1)
    {
        /// x+1 --- y,y+1,y+2
        /// x+2 --- y+1,y+2,y+3
        for(int i=0;i<3;i++)
        {
            int nx=x+1,ny=y+i;
            if(inmap(nx,ny))
            {
                if(tu[nx][ny]!=c) return false;
            }
        }
        for(int i=1;i<4;i++)
        {
            int nx=x+2,ny=y+i;
            if(inmap(nx,ny))
            {
                if(tu[nx][ny]!=c) return false;
            }
        }
    }
    else if(kind==0)
    {
        /// x --- y-1 y+1
        /// x+1 --- y+1 y+2 y+3
        /// x+2 -- y+2

        for(int i=-1;i<=1;i++)
        {
            int nx=x,ny=y+i;
            if(inmap(nx,ny))
            {
                if(tu[nx][ny]!=c) return false;
            }
        }

        for(int i=1;i<=3;i++)
        {
            int nx=x+1,ny=y+i;
            if(inmap(nx,ny))
            {
                if(tu[nx][ny]!=c) return false;
            }
        }

        if(inmap(x+2,y+2))
        {
            if(tu[x+2][y+2]!=c) return false;
        }
    }

    return true;
}

bool check_left(int x,int y,int c,int kind)
{
    if(kind==1)
    {
        /// x -- y-1 y-2 y-3
        /// x-1 y-2,y-3,y-4

        for(int i=1;i<=3;i++)
        {
            int nx=x,ny=y-i;
            if(inmap(nx,ny))
            {
                if(tu[nx][ny]!=c) return false;
            }
        }

        for(int i=2;i<=4;i++)
        {
            int nx=x-1,ny=y-i;
            if(inmap(nx,ny))
            {
                if(tu[nx][ny]!=c) return false;
            }
        }
    }
    else if(kind==0)
    {
        /// x -- y-1 y-2
        /// x-1 -- y-1 y-2 y-3 y-4

        for(int i=1;i<=2;i++)
        {
            int nx=x,ny=y-i;
            if(inmap(nx,ny))
            {
                if(tu[nx][ny]!=c) return false;
            }
        }

         for(int i=1;i<=4;i++)
        {
            int nx=x-1,ny=y-i;
            if(inmap(nx,ny))
            {
                if(tu[nx][ny]!=c) return false;
            }
        }
    }

    return true;
}

bool check_right(int x,int y,int c,int kind)
{
    if(kind==1)
    {
        /// x -- y+1 y+2 y+3
        /// x-1 y y+1 y+2 y+3

         for(int i=1;i<=3;i++)
        {
            int nx=x,ny=y+i;
            if(inmap(nx,ny))
            {
                if(tu[nx][ny]!=c) return false;
            }
        }

         for(int i=0;i<=3;i++)
        {
            int nx=x-1,ny=y+i;
            if(inmap(nx,ny))
            {
                if(tu[nx][ny]!=c) return false;
            }
        }

    }
    else if(kind==0)
    {
        /// x y+1 y+2
        /// x-1 y-1 ... y+3
        for(int i=1;i<=2;i++)
        {
            int nx=x,ny=y+i;
            if(inmap(nx,ny))
            {
                if(tu[nx][ny]!=c) return false;
            }
        }
        for(int i=-1;i<=3;i++)
        {
            int nx=x-1,ny=y+i;
            if(inmap(nx,ny))
            {
                if(tu[nx][ny]!=c) return false;
            }
        }
    }
    return true;
}

bool check_heng()
{
	bool flag=true;
	for(int i=1;i<=n&&flag;i++)
	{
		for(int j=1;j<=2*i-1&&flag;j++)
		{
			if(tu[i][j]==0)
			{
				if(inmap(i,j-1)==false) continue;
				if(tu[i][j-1]==0) continue;
				else flag=false;
			}
		}
	}
	if(flag) return true;
	flag=true;
	for(int i=1;i<=n&&flag;i++)
	{
		for(int j=1;j<=2*i-1&&flag;j++)
		{
			if(tu[i][j]==0)
			{
				if(inmap(i,j+1)==false) continue;
				if(tu[i][j+1]==0) continue;
				else flag=false;
			}
		}
	}
	if(flag) return true;
	return false;
}

bool check_shu()
{
    bool flag=true;
    for(int i=1;i<=n&&flag;i++)
	{
		for(int j=1;j<=2*i-1&&flag;j++)
		{
			if(tu[i][j]==0)
			{
			    if(j%2==1)
                {
                    int nx=i, ny=j+1;
					if(inmap(nx,ny)==false) continue;
                    if(tu[nx][ny]==0) ;
                    else flag=false;
                }
                else if(j%2==0)
                {
                    int nx=i-1, ny=j-1;
					if(inmap(nx,ny)==false) continue;
                    if(tu[nx][ny]==0) ;
                    else flag=false;
                }
			}
		}
	}
	if(flag) return true;
	flag=true;
    for(int i=1;i<=n&&flag;i++)
	{
		for(int j=1;j<=2*i-1&&flag;j++)
		{
			if(tu[i][j]==0)
			{
			    if(j%2==1)
                {
                    int nx=i+1, ny=j+1;
					if(inmap(nx,ny)==false) continue;
                    if(tu[nx][ny]==0) ;
                    else flag=false;
                }
                else if(j%2==0)
                {
                    int nx=i, ny=j-1;
					if(inmap(nx,ny)==false) continue;
                    if(tu[nx][ny]==0) ;
                    else flag=false;
                }
			}
		}
	}
	if(flag) return true;
	return false;
}

bool check_xie()
{
    bool flag=true;
    for(int i=1;i<=n&&flag;i++)
	{
		for(int j=1;j<=2*i-1&&flag;j++)
		{
			if(tu[i][j]==0)
			{
			    if(j%2==1)
                {
                    int nx=i, ny=j-1;
					if(inmap(nx,ny)==false) continue;
                    if(tu[nx][ny]==0) ;
                    else 
                    {
                    	flag=false;
                	}
                }
                else if(j%2==0)
                {
                    int nx=i-1, ny=j-1;
					if(inmap(nx,ny)==false) continue;
                    if(tu[nx][ny]==0) ;
                    else 
                    {
                    	flag=false;
                	}
                }
			}
		}
	}
	if(flag) return true;
	flag=true;
    for(int i=1;i<=n&&flag;i++)
	{
		for(int j=1;j<=2*i-1&&flag;j++)
		{
			if(tu[i][j]==0)
			{
			    if(j%2==1)
                {
                    int nx=i+1, ny=j+1;
					if(inmap(nx,ny)==false) continue;
                    if(tu[nx][ny]==0) ;
                    else 
                    {
                    	flag=false;
                	}
                }
                else if(j%2==0)
                {
                    int nx=i, ny=j+1;
					if(inmap(nx,ny)==false) continue;
                    if(tu[nx][ny]==0) ;
                    else 
                    {
                    	flag=false;
                	}
                }
			}
		}
	}
	if(flag) return true;
	return false;
}

char hang[5000];

int main()
{
	int cas=1;
    while(scanf("%d",&n)!=EOF&&n)
    {
    	printf("Puzzle %d\n",cas++);
    	int zero=0,one=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",hang+1);
            for(int j=1;j<=2*i-1;j++)
            {
                tu[i][j]=hang[j]-'0';
            	if(tu[i][j]==0) zero++;
            	else one++;
            }
        }

        if(one==0||zero==0)
        {
        	puts("Parts cannot be separated"); continue;
        }

        bool flag=true;

        if(check_heng()||check_shu()||check_xie()){puts("Parts can be separated"); continue;}

        for(int i=1;i<=n&&flag;i++)
        {
        	for(int j=1;j<=2*i-1&&flag;j++)
        	{
        		if(tu[i][j]!=0) continue;
        		if(check_down(i,j,0,j%2)) continue;
        		else flag=false;
        	}
        }

        if(flag==true)
        {
        	puts("Parts can be separated"); continue;
        }

        flag=true;
        for(int i=1;i<=n&&flag;i++)
        {
        	for(int j=1;j<=2*i-1&&flag;j++)
        	{
        		if(tu[i][j]!=0) continue;
        		if(check_left(i,j,0,j%2)) continue;
        		else flag=false;
        	}
        }

        if(flag==true)
        {
        	puts("Parts can be separated"); continue;
        }

        flag=true;
        for(int i=1;i<=n&&flag;i++)
        {
        	for(int j=1;j<=2*i-1&&flag;j++)
        	{
        		if(tu[i][j]!=0) continue;
        		if(check_right(i,j,0,j%2)) continue;
        		else flag=false;
        	}
        }

        if(flag==true)
        {
        	puts("Parts can be separated"); continue;
        }
        else
        {
        	puts("Parts cannot be separated");
        }

    }
    return 0;
}




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值