题意:给定一个国际象棋棋盘,左下角为原点建立坐标系,第一象限的左下角为黑色,格宽度为s,给定一个棋子坐标,给定棋子每次移动x,y的变化量。求多就可以跳入白色格子。
分析:在黑色格子中的时候,我们只需要记录其关于当前黑色格子的相对位置(以此格子的左下角为原点),并观察这个相对位置是否被访问过,如果是,那么证明无解。本题特殊之处在于落在边界不算跳入白色。也就是说对于黑色格子的相对位置可能是边界,所以就要区分左右上下边界,这个是难点。
View Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define maxn 1005
long long s, x, y, dx, dy;
bool vis[maxn][maxn];
bool white(long long x, long long y)
{
if (x < s && y < s)
return false;
if (x > s && y > s)
return false;
if (x == s || y == s || x == 0 || y == 0)
return false;
return true;
}
bool make(long long x, long long y)
{
if (x > s || y > s)
{
x -= s;
if (x < 0)
x += 2 * s;
y -= s;
if (y < 0)
y += 2 * s;
}
if (vis[x][y])
return false;
vis[x][y] = true;
return true;
}
void work()
{
memset(vis, 0, sizeof(vis));
long long ansx = x;
long long ansy = y;
long long i = 0;
while (true)
{
x %= 2 * s;
y %= 2 * s;
if (white(x, y))
{
printf("After %lld jumps the flea lands at (%lld, %lld).\n", i, ansx,
ansy);
return;
}
else if (!make(x, y))
{
printf("The flea cannot escape from black squares.\n");
return;
}
ansx += dx;
ansy += dy;
x += dx;
y += dy;
i++;
}
}
int main()
{
//freopen("t.txt", "r", stdin);
while (scanf("%lld%lld%lld%lld%lld", &s, &x, &y, &dx, &dy), s | x | dx | y | dy)
{
work();
}
return 0;
}