您的位置:首页 > 其它

The Tamworth Two

2013-10-12 19:02 375 查看
题意:有一个10×10的网格,网格的每一小格可以是障碍(*),空地(.),农夫(F)或者牛(C)。农夫和牛都有四个朝向,东南西北,初始情况下都朝北。二者都按照下面的规则来运动:如果向前走一步不是障碍或者走出网格,则向前走。否则顺时针改变朝向90度。每一分钟农夫和牛同时运动一步,求什么时候农夫和牛能够相遇在同一格。

解题思路

读入网格的状态,用数组maze[i][j]来保存,初始化为0,读到障碍的时候设为1。在读取过程中保存农夫和牛的初始状态。
农夫和牛的运动一定是有规律的,也就是在若干步(可以是0)以后陷入一个循环。
模拟农夫的运动,用farmer_state[i][j][k]来保存状态,全部初始化为-1。farmer_state[i][j][k] = x,代表在x分钟的时候,农夫走到坐标(i, j)处,并且朝向为k(北东南西分别为0,1,2,3)。
在某一时刻会发现farmer_state[i][j][k] != -1,那么就说明回到了前面的状态,此时农夫开始陷入循环,而且循环的长度就是此时的时间减去前面状态记录的时间。这样在模拟过程中可以记录农夫在何时陷入循环(farmer_repeat_from)和这个循环的长度(farmer_repeat_length)。
得到上述的farmer_state之后对其进行遍历,得到一个新的数组farmer_route[i][j],其中j取0和1。farmer_route[i][0]和farmer_route[i][1]分别代表农夫在经过i步之后所在的网格坐标(x, y)中的x和y。
对牛重复上述3~5操作即可得到相应的cows_state,cows_repeat_from,cows_repeat_length,cows_route。
求farmer_repeat_length和cows_repeat_length的最小公倍数,将其加上farmer_repeat_from和cows_repeat_from中较大的值,得到end_point。
对[0, end_point)这些时刻进行遍历,直到找到一个农夫和牛都处于同一网格的时刻(从farmer_route和cows_route中查找,相应的index用XXX_repeat_from和XXX_repeat_length计算得到)。end_point之后的时刻不需要进行处理,因为后面又会陷入另外一个循环(农夫与牛二者相对状态的循环)。
代码

/*
ID: zc.rene1
LANG: C
PROG: ttwo
*/

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

enum directions{NORTH=0, EAST, SOUTH, WEST};

struct unit
{
int i, j;
int direction;
};

struct unit farmer, cows;
int maze[12][12];
int farmer_state[12][12][4];
int cows_state[12][12][4];

int GetCommonFactor(int a, int b)
{
while ((a != 0)&&(b != 0))
{
if (a > b)
{
a %= b;
}
else
{
b %= a;
}
}
return (a==0)? b:a;
}

void Move(struct unit *in)
{
int new_i = (*in).i;
int new_j = (*in).j;

switch((*in).direction)
{
case 0:
new_i -= 1;
break;
case 1:
new_j += 1;
break;
case 2:
new_i += 1;
break;
case 3:
new_j -= 1;
break;
default:
break;
}

if (maze[new_i][new_j] == 0)
{
if ((*in).direction == 3)
{
(*in).direction = 0;
}
else
{
(*in).direction += 1;
}
}
else
{
(*in).i = new_i;
(*in).j = new_j;
}
}

int main(void)
{
FILE *fin, *fout;
int i, j, k, count, temp;
char *str = NULL;
char lt;
int **farmer_route, **cows_route;

fin = fopen("ttwo.in", "r");
fout = fopen("ttwo.out", "w");

str = (char*)malloc(11*sizeof(char));
memset(maze, 0, 12*12*sizeof(int));
memset(farmer_state, -1, 12*12*4*sizeof(int));
memset(cows_state, -1, 12*12*4*sizeof(int));

for (i=1; i<11; i++)
{
fscanf(fin, "%s", str);
for (j=1; j<11; j++)
{
lt = str[j-1];
if (lt != '*')
{
maze[i][j] = 1;
}
if (lt == 'F')
{
farmer.i = i;
farmer.j = j;
farmer.direction = NORTH;
}
if (lt == 'C')
{
cows.i = i;
cows.j = j;
cows.direction = NORTH;
}
}
}

count = 0;
while (farmer_state[farmer.i][farmer.j][farmer.direction] == -1)
{
farmer_state[farmer.i][farmer.j][farmer.direction] = count;
count++;
Move(&farmer);
}
int farmer_repeat_from = farmer_state[farmer.i][farmer.j][farmer.direction];
int farmer_repeat_length = count - farmer_repeat_from;
farmer_route = (int **)malloc(count*sizeof(int*));
for (i=0; i<count; i++)
{
farmer_route[i] = (int *)malloc(2*sizeof(int));
memset(farmer_route[i], 0, 2*sizeof(int));
}
for (i=1; i<11; i++)
{
for (j=1; j<11; j++)
{
for (k=0; k<4; k++)
{
temp = farmer_state[i][j][k];
if (temp != -1)
{
farmer_route[temp][0] = i;
farmer_route[temp][1] = j;
}
}
}
}

count = 0;
while (cows_state[cows.i][cows.j][cows.direction] == -1)
{
cows_state[cows.i][cows.j][cows.direction] = count;
count++;
Move(&cows);
}
int cows_repeat_from = cows_state[cows.i][cows.j][cows.direction];
int cows_repeat_length = count - cows_repeat_from;
cows_route = (int **)malloc(count*sizeof(int*));
for (i=0; i<count; i++)
{
cows_route[i] = (int *)malloc(2*sizeof(int));
memset(cows_route[i], 0, 2*sizeof(int));
}
for (i=1; i<11; i++)
{
for (j=1; j<11; j++)
{
for (k=0; k<3; k++)
{
temp = cows_state[i][j][k];
if (temp != -1)
{
cows_route[temp][0] = i;
cows_route[temp][1] = j;
}
}
}
}

int greatest_common_factor = GetCommonFactor(farmer_repeat_length, cows_repeat_length);
int greatest_common_multiple = farmer_repeat_length * cows_repeat_length / greatest_common_factor;
int end_point = ((farmer_repeat_from > cows_repeat_from)?farmer_repeat_from:cows_repeat_from) + greatest_common_multiple;

int farmer_index, cows_index;
for (i=0; i<end_point; i++)
{
if (i < farmer_repeat_from)
{
farmer_index = i;
}
else
{
farmer_index = ((i - farmer_repeat_from) % farmer_repeat_length) + farmer_repeat_from;
}

if (i < cows_repeat_from)
{
cows_index = i;
}
else
{
cows_index = ((i - cows_repeat_from) % cows_repeat_length) + cows_repeat_from;
}

if ((farmer_route[farmer_index][0] == cows_route[cows_index][0])&&(farmer_route[farmer_index][1] == cows_route[cows_index][1]))
{
break;
}
}

if (i == end_point)
{
fprintf(fout, "0\n");
}
else
{
fprintf(fout, "%d\n", i);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: