POJ 1600 Centipede Collisions

9 篇文章 0 订阅
4 篇文章 0 订阅

问题描述:

Description

A small boy named Tommy has some toy centipedes that are a series of 1 centimeter segments. Tommy assembles his centipedes to any length he likes and places them on a 30x30 centimeter board that allows the centipedes to travel in 1 centimeter wide tracks that criss-cross the board. The centipedes travel only parallel to either the x or y axis on the board. Centipede segments of the same centipede advance at the same time and centipedes advance in cyclic numerical order (all of centipede 0 first, then 1, etc.). When more than one segment of two or more centipedes occupy the same x,y coordinate, there is a centipede collision. Anytime a collision occurs, all segments occupying the collistion site stop and continue to occupy the collision site. All remaining segments on a centipede detach from the segment involved in the collision and continue their march until another collision occurs or an existing collision site is encountered or until the segments fall off the edge of the board. Anytime a segment enters a collision site, it becomes part of the collision. 

Since Tommy left home without his centipede set, his mother has hired you to write a simulation program for his entertainment. Your program will simulate his board with a text printout of his grids. For example, Tommy may simulate 5 centipedes on his board that start out as shown on the grid on the left and finish as shown on the grid on the right (note the example grid is only 10x10 whereas Tommy's is 30x30.) 
   9    . . . . . . . . . .            9    . . . . . . . . . .

   8    . . . . . . . . . .            8    . . . . . . . . . .

   7    1 1 1 1 1 . . . . .            7    . . . . . X . . . X

   6    . 0 . . . . . . . .            6    . . . . . . . . . .

   5    . 0 . . . . . . . 3            5    . . . . . . . . . .

   4    . 0 . . . 2 . . . 3            4    . . . . . . . . . .

   3    . 0 . . . 2 . . . 3            3    . . . . . . . . . .

   2    . . . . . 2 . . . 3            2    . . . . . . . . . .

   1    . . . . . 2 . . . 3            1    . . . . . . . . . .

   0    . . . . . 2 4 4 4 3            0    . X . . . . . . . .

   Y                                   Y

    / X 0 1 2 3 4 5 6 7 8 9             / X 0 1 2 3 4 5 6 7 8 9

Where 0 represents a centipede segment traveling from top to bottom, 
1 represents a centipede segment traveling from left to right, 
2 represents a centipede segment traveling from bottom to top, 
3 represents a centipede segment traveling from bottom to top, 
4 represents a centipede segment traveling from right to left, and 
X represents a collision site involving 2 or more segments. 

Your program will simulate up to 10 centipedes that travel on a 30x30 board. Tommy has 100 segments that he may use in his simulation. Of course, no centipede can be longer than 30 segments. 

Input

Input to your program will consist of a series of simulation sets. The first line of each input set will be a single integer (1<=N<=10) representing the number of centipedes in the simulation. (Centipedes are numbered 0 through N-1 in the same order as the input.) The next N lines will each represent one centipede and will contain a single direction character followed by 3 integers. The direction character can be 'U', 'D', 'L', or 'R' for "Up", "Down", "Left", or "Right" respectively and indicate the direction of travel. The next integer (1<=L<=30) indicates the length of the centipede in segments. The second and third integers indicate the x,y coordinates of the lead segment (0<=x&y<=29). The next L-1 segments of the centipede occupy the L-1 board positions extending in the opposite direction from the direction of travel starting adjacent to the lead segment. You can be assured that no centipede segment will originate off the board nor will the original configuration involve any collisions.

Output

For each input simulation set, you should print (exactly) the following lines as the first two lines of output (starting in column 4). 

0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 

The next 30 lines represent the state of the board after the simulation has completed (all centipede segments have entered a collision site or fallen off the edge of the board). Columns 1 and 2 should contain the row number (rows are numbered 29 down to 00) with leading zeroes. Even numbered columns between 4 and 62 (inclusive) represent the contents of the board cells. Board cells can contain either an X or a period. A period represents an empty cell and X represents a cell that contains 2 or more centipede segments involved in a collision. The last line of each output set is a blank line. 

Follow the Sample Output for the exact format of the expected output. 

Sample Input

10
R 9 11 23
U 8 11 17
U 5 15 15
U 5 15 8
D 9 23 13
U 6 23 6
R 9 8 9
L 13 17 0
U 12 13 11
L 5 20 9

解法:

本题蜈蚣长度消减的情况共有3中,第一种,蜈蚣的头碰到了边界,此时每一次循环,蜈蚣的长度都会减一(见(××));第二种,蜈蚣的头的前面一个是冲突点,此种情况下,每经过一次循环,蜈蚣的长度减一(见(××));第三种,蜈蚣的头碰到了另一个蜈蚣的身体。因为蜈蚣只有一个头,所以蜈蚣只能碰到另一个唯一的蜈蚣的身体,此时本蜈蚣的长度减一,并制造了一个永久冲突点。另一条蜈蚣(在前进方向上意义上的)在冲突点前面的身体可以脱离冲突点继续前进,冲突点后面的身体只能陷入冲突点了。所以这时候另一条蜈蚣可能分成了两份。具体分法见DivideCenpede(int,int,int);第一个int是要分裂的蜈蚣的编号,第二个和第三个int分别是冲突点的x坐标和y坐标。至于为什么要并且把分开的,蜈蚣后面的身体算一条独立的蜈蚣,是因为分开的身体部分有可能挡住别的蜈蚣的前进道路。此蜈蚣的前进方向和父蜈蚣的前进方向相同。(这是第三种情况的子程序。(×××))。

然后可以写了。


下面是代码:

#include<iostream>
#include<iomanip>
#include<fstream>
#include<cmath>
#include<cstring>
using namespace std;

ifstream fin("CentipedeCollisions.in");

int N,length[100],leadPos[100][100],direction[100][100];
int grid[30][30];
char direc[10];

int legend1[30]={0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2};
int legend2[30]={0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9};

void print()
{
	cout<<setw(2)<<" ";
	for(int i=0;i<30;++i)
		cout<<setw(2)<<legend1[i];
	cout<<endl;
	cout<<setw(2)<<" ";
	for(int i=0;i<30;++i)
		cout<<setw(2)<<legend2[i];
	cout<<endl;
	for(int i=0;i<30;++i)
	{
		cout<<setw(2)<<setfill('0')<<29-i<<setfill(' ');
		for(int j=0;j<30;++j)
		{
			if(grid[i][j]==0)
				cout<<setw(2)<<".";
			else
				cout<<setw(2)<<"X";
		}
		cout<<endl;
	}
}

void InitDirection()
{
	for(int i=0;i<N;++i)
	{
		if(direc[i]=='R')
		{
			direction[i][0]=1;
			direction[i][1]=0;
		}
		else if(direc[i]=='L')
		{
			direction[i][0]=-1;
			direction[i][1]=0;
		}
		else if(direc[i]=='U')
		{
			direction[i][0]=0;
			direction[i][1]=1;
		}
		else
		{
			direction[i][0]=0;
			direction[i][1]=-1;
		}
	}
}

void DivideCentipede(int pos,int x,int y)
{
	int length1,length2;
	length1=direction[pos][0]!=0?abs(leadPos[pos][0]-x):abs(leadPos[pos][1]-y);
	length2=length[pos]-1-length1;
	if(length2>0)
	{
		length[N]=length2;
		leadPos[N][0]=x-direction[pos][0];
		leadPos[N][1]=y-direction[pos][1];
		direction[N][0]=direction[pos][0];
		direction[N][1]=direction[pos][1];
		++N;
	}
}

void search()
{
	bool canExist=false;
	while(!canExist)
	{
		canExist=true;
		for(int i=0;i<N;++i)
		{
			if(length[i]>0)
			{
				int p1,p2;
				p1=direction[i][0]!=0?0:1;
				p2=p1==0?1:0;
				if(!(leadPos[i][p1]+direction[i][p1]>=0&&leadPos[i][p1]+direction[i][p1]<=29))
				{
					--length[i];
				}
				else if(grid[leadPos[i][0]+direction[i][0]][leadPos[i][1]+direction[i][1]]==1)
				{
					--length[i];
				}
				else
				{
					bool getCollision=false;
					for(int j=0;j<N;++j)
					{
						if(j!=i&&length[j]!=0)
						{
							if(leadPos[i][p1]+direction[i][p1]==leadPos[j][p1])
							{
								if((leadPos[j][p2]-leadPos[i][p2])*(leadPos[j][p2]-direction[j][p2]*(length[j]-1)-leadPos[i][p2])<=0)
								{
									--length[i];
									getCollision=true;
									int x,y;
									x=leadPos[i][0]+direction[i][0];
									y=leadPos[i][1]+direction[i][1];
									grid[x][y]=1;
									DivideCentipede(j,x,y);
									break;
								}
							}
						}
					}
					if(!getCollision)
					{
						leadPos[i][p1]+=direction[i][p1];
					}
				}
			}
		}
		for(int m=0;m<N;++m)
		{
			if(length[m]!=0)
			{
				canExist=false;
				break;
			}
		}
	}
}

int main()
{
	memset(length,0,sizeof(length));
	memset(leadPos,0,sizeof(leadPos));
	memset(direction,0,sizeof(direction));
	memset(grid,0,sizeof(grid));
	memset(direc,0,sizeof(direc));
	fin>>N;
	for(int i=0;i<N;++i)
	{
		fin>>direc[i]>>length[i]>>leadPos[i][0]>>leadPos[i][1];
	}
	InitDirection();
	search();
	print();
	return 0;
}


这道题我怀疑题中的给的数据有问题,见示例输入的第七组数据。


这个可以写个程序做个游戏来做动态展示(和题目中的提示一样)。不过我现在用的是ubuntu,没法用VC来写。寒假回家再写吧。先放在这里了。

小程序

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值