USACO Training Section 2.4 The Tamworth Two

[url="http://ace.delos.com/usacoprob2?a=F8SQKyzbWbG&S=ttwo"]英文原题[/url] [url="http://www.wzoi.org/usaco/12%5C209.asp"]中文题译[/url]

大意:奶牛丢了,农民要找牛。牧场是一块方形区域,其中有障碍物,奶牛每分钟走一格,如不遇到障碍或者到达边界不转向,每次转向费时一分钟,且总顺时针转向。农民也按次策略行动,给定牧场图,奶牛与农民的初始位置,问什么时候能找到牛,或者告知找不到牛。

简单的离散模拟。有几点要说的:
1.在处理输入时候把边界全部处理成障碍,可不用特别判断边界。不过我在这里犯了错,数组设定没做好结果输入越界,浪费了时间,晕。
2.如何判断不能找到牛?农民和奶牛的移动一定会在某时刻重复(相同位置、相同方向),记录重复的周期,在两个周期的最小公倍数范围内如果找不到牛,就永远找不到。看了看标程,很无耻的直接设了个1600,这是不对的。
3.是用结构体记录位置、状态,还是直接记录?这里用的是struct,程序看起来简洁一些。


/*
ID: blackco3
TASK: ttwo
LANG: C++
*/
#include <iostream>
#include <memory.h>
using namespace std;
#define _size_ 10
int grid[_size_+2][_size_+2];
struct t_pos {
int row, col ;
t_pos( int r=0, int c=0 ): row(r), col(c) {} ;
} ;
t_pos step[4]={t_pos(-1,0), t_pos(0,1), t_pos(1,0), t_pos(0,-1)}; /*N->E->S->W->N : clockwise turn*/
inline t_pos operator + ( t_pos const & p1, t_pos const & p2 ){
return t_pos( p1.row+p2.row, p1.col+p2.col );
}
inline bool operator == ( t_pos const & p1, t_pos const & p2 ){
return p1.row==p2.row && p1.col==p2.col ;
}

struct t_fc {
t_pos pos ;
int dir, vis[_size_][_size_][4], loop_step, n_move ;
inline void init(int row, int col ) {
pos = t_pos(row,col);
memset( vis, 0, sizeof(vis) );
dir=0, vis[row][col][dir]=1, loop_step=0, n_move=0 ;
};
inline void move() {
t_pos next = pos + step[dir] ;
n_move++ ;
if( !grid[next.row][next.col ] )
dir = (++dir)%4 ;
else
pos = pos + step[dir] ;
if( vis[pos.row][pos.col][dir]==1 && !loop_step ){
loop_step=n_move ;
}
vis[pos.row][pos.col][dir] = 1 ;
}
} farmer, cows ;

int gcd( int a, int b ){
int tmp ;
while( b )
tmp= a%b, a = b, b=tmp ;
return a ;
}

int main() {
freopen("ttwo.in", "r", stdin);
freopen("ttwo.out", "w", stdout);
char grid_str[_size_+2] ;
memset( grid, 0, sizeof(grid) );
for( int row=1; row<=_size_; row++){
cin >> (grid_str+1) ;
for( int col=1; col<=_size_; col++){
grid[row][col] = (grid_str[col]!='*');
if( grid_str[col]=='F' )
farmer.init( row, col) ;
else if(grid_str[col]=='C' )
cows.init( row, col );
}
}
for( int step=1, max_step=0; !max_step || step<=max_step; step++ ){
farmer.move(), cows.move() ;
if( farmer.pos==cows.pos ) {
cout << step << endl ;
return 0 ;
}
if( !max_step && farmer.loop_step && cows.loop_step )
max_step = farmer.loop_step*cows.loop_step/gcd( farmer.loop_step, cows.loop_step ) ;
}
cout << 0 << endl ;
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值