问题描述:
Description
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
Input
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来写。寒假回家再写吧。先放在这里了。