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;
}
时间: 2024-10-13 17:22:54

ZOJ 2610 Puzzle 模拟的相关文章

ZOJ 3705 Applications 模拟

#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include<sstream> #include<cmath> #include<climits&g

ZOJ 3019 Puzzle

解题思路:给出两个数列an,bn,其中an,bn中元素的顺序可以任意改变,求an,bn的LCS 因为数列中的元素可以按任意顺序排列,所以只需要求出an,bn中的元素有多少个是相同的即可. 反思:一开始以为就是求LCS,一直WA,后来才发现可以按任意顺序排列元素,把相同的元素都排在一起,就是最长的子序列. Puzzle Time Limit: 2 Seconds      Memory Limit: 65536 KB For sequences of integers a and b, if yo

A - Jugs ZOJ - 1005 (模拟)

题目链接:https://cn.vjudge.net/contest/281037#problem/A 题目大意:给你a,b,n.a代表第一个杯子的容量,b代表第二个杯子的容量,然后一共有6种操作.让你用尽可能少的步骤将第二个杯子的当前的水的体积转换成n. 具体思路:就是队列模拟啊,,,,打比赛的时候脑子瓦特了,没读完题目就开始读了,,,这个毛病确实得改了,, AC代码: 1 #include<iostream> 2 #include<stack> 3 #include<io

[ZOJ 1009] Enigma (模拟)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1009 题目大意:给你三个转换轮,只有当第一个转换轮转动一圈后第二个才会转,当第二个转动一圈后第三个才会转.转换轮的意思是我按动一个按钮,显示器经过转换轮的转换显示另外一个字母.每按下一个按钮,第一个转换轮都会转动一次. 叉姐说得好,多学习一下思维方法,有些问题都是能够很高效率的想出来的.脑洞什么的全是骗人的. 注意看这张图: 中间转动轮的点, 左右两边是一一对应

ZOJ 3652 Maze 模拟,bfs,读题 难度:2

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4842 要注意题目中两点: 1.在踏入妖怪控制的区域那一刹那,先减行动力,然后才能杀妖怪 2.在妖怪控制区域行动力也会恢复 3.妖怪也许不在自己的控制区域 #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace st

2018 German Collegiate Programming Contest (GCPC 18)

2018 German Collegiate Programming Contest (GCPC 18) Attack on Alpha-Zet 建树,求lca 代码: #include <algorithm> #include <iterator> #include <iostream> #include <cstring> #include <cstdlib> #include <iomanip> #include <bit

ZOJ 3814 Sawtooth Puzzle(牡丹江网络赛F题)

ZOJ 3814 Sawtooth Puzzle 题目链接 记录状态广搜,把9个拼图都压缩成一个状态,然后去搜索,就是模拟的过程比较麻烦 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <set> using namespace std; typedef unsigned long long ll; int t; int

[容斥原理] zoj 2836 Number Puzzle

题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1836 Number Puzzle Time Limit: 2 Seconds      Memory Limit: 65536 KB Given a list of integers (A1, A2, ..., An), and a positive integer M, please find the number of positive integers th

ZOJ 2836 Number Puzzle ( 容斥原理 )

ZOJ 2836 Number Puzzle( 容斥原理 ) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; #define CLR( a, b ) memset( a, b, sizeof(a) ) int m, n, A[11]; LL gcd( LL a, LL b ) { return b == 0 ? a :