UVA 10620 - A Flea on a Chessboard(鸽笼原理)

UVA 10620 - A Flea on a Chessboard

题目链接

题意:给定一个跳蚤位置和移动方向,现在在一个国际象棋棋盘上,左下角为黑格,一个格子为s*s,判断能否移动到白格子,问要移动多少次才能到白格,边界不算白格。

思路:利用鸽笼原理落在黑格子和边界上的一共有(s + 1)^2个点,也就是说,如果形成循环,周期肯定在这之内,所以可以不断去模拟跳格子,直到踩到白格,或者踩到之前落到过的黑格就结束

不过其实还有更优的方法,因为跳蚤跳跃路径为直线,观察下可以发现如果可以到白格,最多连成一条小于(2 x 2)格子对角线长度的线,那么上面一共有不超过2 * s个黑点,于是其实只需要判断前2s步能不能到白格就可以了,如果不能,说明必然中间形成了周期,也就是始终到不了白格了

代码:

原来的:

#include <stdio.h>
#include <string.h>

const int N = 1005;
bool vis[N][N];
long long s, x, y, dx, dy;

bool white() {
    if (x % s == 0 || y % s == 0) return false;
    if (((x / s)&1)^((y / s)&1)) return true;
    return false;
}

bool in() {
    if (x > s || y > s) {
	x -= s; y -= s;
	if (x < 0) x = s;
	if (y < 0) y = s;
    }
    if (vis[x][y]) return false;
    vis[x][y] = true;
    return true;
}

int main() {
    while (~scanf("%lld%lld%lld%lld%lld", &s, &x, &y, &dx, &dy) && s) {
	memset(vis, false, sizeof(vis));
	long long ans = 0, ansx = x, ansy = y;
	while (1) {
	    x %= 2 * s;
	    y %= 2 * s;
	    if (white()) {
		printf("After %lld jumps the flea lands at (%lld, %lld).\n", ans, ansx, ansy);
		break;
	    }
	    if (!in()) {
		printf("The flea cannot escape from black squares.\n");
		break;
	    }
	    x += dx;
	    y += dy;
	    ansx += dx;
	    ansy += dy;
	    ans++;
	}
    }
    return 0;
}

简化后的:

#include <stdio.h>
#include <string.h>

long long s, x, y, dx, dy;

bool judge(long long x, long long y) {
    return (x % s && y % s && (x / s + y / s) % 2);
}

int main() {
    while (~scanf("%lld%lld%lld%lld%lld", &s, &x, &y, &dx, &dy) && s) {
	int i;
	for (i = 0; i < 2 * s; i++) {
	     if (judge(x, y)) {
		 printf("After %d jumps the flea lands at (%lld, %lld).\n",i,x,y);
		 break;
	     }
	     x += dx; y += dy;
	}
	if (i == 2 * s) printf("The flea cannot escape from black squares.\n");
    }
    return 0;
}

UVA 10620 - A Flea on a Chessboard(鸽笼原理),布布扣,bubuko.com

时间: 2024-10-20 10:29:41

UVA 10620 - A Flea on a Chessboard(鸽笼原理)的相关文章

uva 10620 - A Flea on a Chessboard(暴力+数学)

题目链接:10620 - A Flea on a Chessboard 题目大意:在一个国际象棋的棋盘上,以左下角作为坐标轴建立坐标系,并且左下角的格子为黑色,每个格子边长为s.假定棋盘无限大,给定跳蚤的起始位置和方向,问这个苦逼的跳蚤能否跳到白格子. 解题思路:枚举前s*2步即可,因为2*2的格子形成了2白两黑的最小单位,边长为2*s,2*s步等于是跳回了相应的起始位置. #include <cstdio> #include <cstring> int s, x, y, dx,

UVA 11237 - Halloween treats(鸽笼原理)

11237 - Halloween treats 题目链接 题意:有c个小伙伴,n个房子(c <= n),每个房子会给ai个糖果,要求选一些房子,使得得到的糖果能平均分给小伙伴,输出方案 思路:c <= n 这个条件很关键,如果有这个条件,那么就可以开一个sum[i]记录0 - i的前缀和%c的值,这样一来在长度n的数组中,必然会出现重复的两个值,用sum[i] - sum[j] == 0这个区间就必然是所求的答案 代码: #include <cstdio> #include &l

HDU 5762 Teacher Bo (鸽笼原理) 2016杭电多校联合第三场

题目:传送门. 题意:平面上有n个点,问是否存在四个点 (A,B,C,D)(A<B,C<D,A≠CorB≠D)使得AB的横纵坐标差的绝对值的和等于CD的横纵坐标差的绝对值的和,n<10^5,点的坐标值m<10^5. 题解:表面上这道题复杂度是O(n^2)会超时的,而实际上这些坐标差绝对值的和最大是2*10^5,所以复杂度不是O(n^2),而是O(min(n^2,m)),这就是著名的鸽笼原理. #include <iostream> #include <cstdio

POJ 2356 Find a multiple (dp + 鸽笼原理)

OJ题目:click here~~ 题目分析:n个数,从中取若干个数,和为n的倍数.给出一种取法. 因为只要给出其中一种方案就行,鸽笼原理可以求出取出的数为连续的方案. 关于鸽笼原理,点这里~ 直接贴过来: 有n+1件或n+1件以上的物品要放到n个抽屉中,那么至少有一个抽屉里有两个或两个以上物品. 如果你知道这个结论: a1,a2,a3...am是正整数序列,至少存在整数k和r,1<=k<r<=m,使得ak+a(k+1)+...+a(r)是m的倍数. 证明比较简单: Sk表示前k个数之和

[51NOD1103] N的倍数(鸽笼原理)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1103 这题一脸组合数学鸽笼原理例题的样子. 这个问题自己其实YY过很久了,结果今天看到又给忘了.大概是因为没有手写过,希望下次不再忘了. 求前缀和,再对n取模.假如有模为0的,那么就直接拿出来前1~i个数. 如果没有0,那么模数只有n-1个,相对与一共有n个前缀和,根据鸽笼原理,必然有一个模数出现了两次,那这出现了两次的模数位置找出来,把这些数输出就行了.

poj3370Halloween treats(鸽笼原理)

题目链接: 传送门 思路: 这个是鸽笼原理的题目...看了一下这个原理,对此的理解是分为三点.. c代表人的数目,n代表家庭的数目.. [1]首先要求前缀和,然后对此取余,首先如果出现余数为0的情况,那么说明前n项就已经满足了条件,那么这就是其中的一组可行解... [2]但是如果没有出现0呢??那么就看同余了..如果在两个点处出现同余,说明什么??说明从上一个出现同余的后一个数到这个数的和为c的倍数,那么就得到了一组可行解.. [3]题目说没有情况则输出"no sweetws",但是说

poj2356Find a multiple(鸽笼原理)

题目链接: huangjing 思路: 详见传送门 题目: Find a multiple Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6015   Accepted: 2609   Special Judge Description The input contains N natural (i.e. positive integer) numbers ( N <= 10000 ). Each of that num

hdu1205 吃糖果(鸽笼原理)

题目链接: huangjing 思路: 这个题我是这样想的,把其他颜色的糖果当成挡板,必过有n个,那么就可以形成n+1个位置,那么如果n+1大于最大堆糖果树,那么就可以吃到所有不同的糖果,但是有可能会说,万一其他颜色的糖果冲突呢????但是因为其他每种颜色的糖果的数目必然小于最大的,那么可以把这些插入到最大堆的糖果和其他颜色中,相当于加大板子的厚度.... 题目: 吃糖果 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/

poj3370 鸽笼原理

题意:首先输入c n,接着是n个数,问你有没有k个数(1<=k<=n),使得其和能整除c 输出其对应下标,只输出一组符合条件的就行: 分析:http://blog.csdn.net/bigsungod/article/details/41450729 代码: #include <queue> #include <stack> #include <math.h> #include <vector> #include <limits.h>