ACM复习(17)8620 国际象棋棋盘

Description 信息学院的新生大一是不准带电脑的(当然,部分”机”胆包天者不予讨论),有时夜晚太无聊怎么办呢?下象棋是一个不错的消遣。下面是一个基于国际象棋的游戏。 一个国际象棋棋盘,由黑色和白色的正方形格子相隔组成。假设棋盘左上角坐标为原点(0,0),向右为x轴正方向,向下为y轴正方向,每个格子阔度为S厘米(1<=S<=1000)。一开始有一个棋子在某个点上,每次棋子可以向右移动dx厘米而且向下移动dy厘米(如果dx=1,dy=2,棋子一开始在原点,则第一次移动后,棋子的坐标为(1,2))。当然,每次棋子所在坐标的颜色有3种可能:假设S=5,黑色(如坐标(2,3))、白色(如坐标(7,2))、黑白边界(如坐标(5,2))。本题问题就是:给出S,dx,dy,起始坐标x,y,问棋子需要移动多少次到达一个白色的坐标(黑白边界的位置不算)。 注意:有可能一次都不用移动或者无论怎么移动都无法到达。

这里写图片描述

输入格式 多Cases, 每行5个整数:S,x,y,dx,dy,以5个0结束输入

输出格式 输出需要移动次数及当时坐标,如样例,若无法成功,输出“The flea cannot escape from black squares.”

输入样例
10 2 3 3 2
100 49 73 214 38
25 0 0 5 25
407 1270 1323 1 1
18 72 6 18 6
407 1270 1170 100 114
0 0 0 0 0

输出样例
After 3 jumps the flea lands at (11, 9).
After 1 jumps the flea lands at (263, 111).
The flea cannot escape from black squares.
After 306 jumps the flea lands at (1576, 1629).
The flea cannot escape from black squares.
After 0 jumps the flea lands at (1270, 1170).


解题思路

记录起始点的坐标特征(例如在格子内还是边框,在格子内时距格子左上角的距离,在边框时左右分别是什么颜色的格子等等),然后一步一步模拟,当再次走到和起始点具有相同特征的坐标时判定白格不可到达,不然总会走到白格的。

PS:这道题有一个超级大坑,就是当判定无法到达白格时输出的那个字符串,如果直接printf那么代码无法提交,那个字符串一定要分成两个部分printf才可以!!!不信你可以把我代码中那个printf语句合并起来试试能不能提交。但是我发现别人的代码就可以合并起来!!!!

#include<iostream>
#include<cstdio>
using namespace std;
int calculate(int s, int x, int y, int &ff, int &fx, int &fy);
int main()
{
    int s, dx, dy, x, y, count, ff, fx, fy, ef, ex, ey;
    while(cin >> s >> x >> y >> dx >> dy && s)
    {
        if(calculate(s, x, y, ff, fx, fy))
            printf("After 0 jumps the flea lands at (%d, %d).\n", x, y);
        else
        {
            count = 0;
            while(1)
            {
                count += 1;
                x += dx; 
                y += dy;
                if(calculate(s, x, y, ef, ex, ey))
                {
                    printf("After %d jumps the flea lands at (%d, %d).\n", count, x, y);
                    break;
                }
                if(ff == ef && fx == ex && fy == ey)
                {
                    // 这两句printf不能合并,不然代码无法提交
                    printf("The flea cannot escape from");
                    printf(" black squares.\n");
                    break;
                }
            }           
        }
    }
    return 0;
}
// ff当前坐标状态类型
// fx,fy当前状态相应特征值
int calculate(int s, int x, int y, int &ff, int &fx, int &fy)
{
    // 在边界
    if(x % s == 0 || y % s == 0)
    {
        // 交叉点
        if(x % s == 0 && y % s == 0)
        {
            fx = fy = 0;
            ff = 2;
        }
        else if(x % s == 0)
        {
            // 左黑右白
            if((x / s + y / s) % 2 == 1)
                ff = 3;
            else
                ff = 4;
            fx = 0;
            fy = y - y / s * s;
        }           
        else
        {
            // 上黑下白
            if((x / s + y / s) % 2 == 1)
                ff = 5;
            else
                ff = 6;
            fy = 0;
            fx = x - x / s * s;
        }
    }
    else
    {
        // 白格内
        if((x / s + y / s) % 2 == 1)
            return 1;
        // 黑格内
        else
        {
            ff = 0;
            fx = x - x / s * s;
            fy = y - y / s * s;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值