您的位置:首页 > 其它

UVa 10413 Crazy Savages(扩展欧几里得)

2013-10-01 20:07 483 查看


UVa 10413 Crazy Savages(扩展欧几里得)

分类: ACM_数论and数学类 ACM_UVa2013-10-01
17:06 73人阅读 评论(0) 收藏 举报

题意:

有m个洞穴成一个环状,现在有n个野蛮人,给你每个野蛮人的初始位置c[i],每个野蛮人下一天要去顺时针的第p[i]个洞穴,每个野蛮人存活天数为l[i],如果某一天两个野蛮人来到同一个洞穴,就会打架了~必须要死一个了~现在给你所有的条件除了m,问m至少为多少才能保证没有野蛮人打架死亡的。

解题思路:

枚举m,初始的m由输入数据决定,如果第i个人和第j个人在某一天碰到一起了,可以这样表示

(c[i] + x*p[i])%m = (c[j] + x*p[j])%m,即:c[i] + x*p[i] = c[j] + x*p[j] + y*m(x,y为未知数),问题就转换成一元二次方程求解了,扩展欧几里得简单搞起。

[cpp] view
plaincopy

/* **********************************************

Author : JayYe

Created Time: 2013/10/1 16:50:11

File Name : JayYe.cpp

*********************************************** */

#include <stdio.h>

#include <string.h>

#include <algorithm>

using namespace std;

//扩展欧几里得

int exgcd(int a, int b, int &x, int &y) {

if(!b) {

x = 1; y = 0;

return a;

}

int ret = exgcd(b, a%b, y, x);

y -= a/b*x;

return ret;

}

int c[22], p[22], l[22], n;

bool solve(int m) {

for(int i = 0;i < n; i++) {

for(int j = i+1;j < n; j++) {

int x, y;

int d = exgcd(p[j]-p[i], m, x, y);

if( (c[i]-c[j])%d ) continue;

x *= (c[i]-c[j])/d;

if(d < 0) d = -d;

x = (x%(m/d) + m/d)%(m/d);

// 在两个人都没死之前碰面

if(x <= l[i] && x <= l[j]) return false;

}

}

return true;

}

int main() {

int t;

scanf("%d", &t);

while(t--) {

scanf("%d", &n);

int ans = 0;

for(int i = 0;i < n; i++) {

scanf("%d%d%d", &c[i], &p[i], &l[i]);

c[i]--;   // 从0开始方便处理

ans = max(ans, c[i] + 1);

}

while(true) {

if(solve(ans)) break;

ans++;

}

printf("%d\n", ans);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: