The Tamworth Two

来源:互联网 发布:bool c语言 编辑:程序博客网 时间:2024/05/22 14:04

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


解题思路

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

代码

/*ID: zc.rene1LANG: CPROG: 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;}
























原创粉丝点击