HDU4452

HDU4452 Running Rabbits

现在有TOM和JERRY两只兔子,他们都在N*N的方阵上向东西南北四个方向跑动,TOM从左上角(1,1)开始,JERRY从右下角(N,N)开始。

假设5*5的方阵,一个兔子当前在(3,2)以每小时3格的速度往西走,那么它在遇到边界的时候会往反方向走。1秒后它在(3,3)。

兔子们都在0点开始运动,且如果TOM和JERRY在某一整点时刻相遇了,那么TOM和JERRY会互换方向(即他们的方向互换)。如果他们相遇的时候在一个边界,他们还是依然互换方向。再下一秒才判断兔子们的新方向是否撞墙导致反向跑。

且兔子们都会以一定的周期t小时来向当前方向的左边转,如果t=2则,他在2,4,6,8等时回左转。现在要求K秒后,两个兔子分别的坐标。

输入:输入包含多组实例。每个实例第一个为N( 2≤N≤20),第二行为TOM的属性C S T。C为初始方向,为'W','E','N' or 'S'。S为初始速度( 1≤S<N)。T为左转周期。第三行为JERRY的属性格式为C S T.

第四行为一个K( 1 ≤ K ≤ 200),表示要计算第K小时后两个兔子的坐标。

输出:分别输出两个兔子K秒后的坐标。

分析:每个兔子的属性为:坐标,运动方向,左转周期。然后从0点开始计算每个兔子的下一小时状态,兔子在下一小时有1兔子重叠,2兔子周期性左转,3兔子撞墙反向转,三种情况发生。

当有1时 不计算2

否则只计算2

3情况只发生在兔子每小时运动的过程中。

AC代码:

#include<cstdio>
using namespace std;
const int WEAST=0,EAST=1,NORTH=2,SOUTH=3;//定义4个方向
int dx[]={0,0,-1,1};//dx[WEAST]=0表往西走时,X坐标加0,X为行标
int dy[]={-1,1,0,0};//y为列标
int inv[]={1,0,3,2};//inv[WEST]=1=EAST表西的反方向是东
int turn_left[]={SOUTH,NORTH,WEAST,EAST};//turn_left[WEAST]=SOUTH朝西时左转变为朝南
int main()
{
    int n;
   while(scanf("%d",&n)==1&&n)//方阵N*N
    {
        intc[2],s[2],t[2],x[2],y[2];//C,S,T含义按题意,x,y表坐标
       x[0]=y[0]=1;//TOM起始坐标
       x[1]=y[1]=n;//JERRY起始坐标
        chardir;
        for(inti=0;i<2;i++)
        {
           scanf(" %c %d %d",&dir,&s[i],&t[i]);//读C,S,T
           switch(dir)//判断起始运动方向
            {
               case'W':c[i]=0;break;
               case'E':c[i]=1;break;
               case'N':c[i]=2;break;
               case'S':c[i]=3;break;
            }
        }
        int k;//计算K秒后
       scanf("%d",&k);
        for(inttime=1;time<=k;time++)//第time秒
        {
           //printf("the %d second:\n",time);
           for(int i=0;i<2;i++)//第i只兔子
            {
               //printf("%d rab\n",i);
               for(int j=1;j<=s[i];j++)//第time秒时第i只兔子的第j步走法(共S[i]步)
               {
                   //printf("%d step in %d steps\n",j,s[i]);
                    x[i]=x[i]+dx[c[i]];
                   y[i]=y[i]+dy[c[i]];
                   if(x[i]<1||x[i]>n)//越界判断
                   {
                       c[i]=inv[c[i]];
                       if(x[i]<1)x[i]=2;
                       else x[i]=n-1;
                   }
                   else if(y[i]<1||y[i]>n)//越界判断
                   {
                       c[i]=inv[c[i]];
                       if(y[i]<1)y[i]=2;
                       else y[i]=n-1;
                    }
                   //printf("i=%d x=%d y=%d\n",i,x[i],y[i]);
               }
            }
           if(x[0]==x[1]&&y[0]==y[1])//兔子位置重叠
            {
               int t=c[0];
               c[0]=c[1];
               c[1]=t;
            }
            elseif(time%t[0]==0||time%t[1]==0)//周期左转
            {
               if(time%t[0]==0)c[0]=turn_left[c[0]];
               if(time%t[1]==0)c[1]=turn_left[c[1]];
            }
        }
       printf("%d %d\n",x[0],y[0]);//最终坐标
        printf("%d %d\n",x[1],y[1]);
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值