现在的位置: 首页 > 综合 > 正文

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

2017年12月13日 ⁄ 综合 ⁄ 共 1753字 ⁄ 字号 评论关闭
 

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

分类: ACM_数论and数学类 ACM_UVa 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为未知数),问题就转换成一元二次方程求解了,扩展欧几里得简单搞起。


  1. /* ********************************************** 
  2. Author      : JayYe 
  3. Created Time: 2013/10/1 16:50:11 
  4. File Name   : JayYe.cpp 
  5. *********************************************** */  
  6.   
  7. #include <stdio.h>  
  8. #include <string.h>  
  9. #include <algorithm>  
  10. using namespace std;  
  11. //扩展欧几里得  
  12. int exgcd(int a, int b, int &x, int &y) {  
  13.     if(!b) {  
  14.         x = 1; y = 0;  
  15.         return a;  
  16.     }  
  17.     int ret = exgcd(b, a%b, y, x);  
  18.     y -= a/b*x;  
  19.     return ret;  
  20. }  
  21.   
  22. int c[22], p[22], l[22], n;  
  23.   
  24. bool solve(int m) {  
  25.     for(int i = 0;i < n; i++) {  
  26.         for(int j = i+1;j < n; j++) {  
  27.             int x, y;  
  28.             int d = exgcd(p[j]-p[i], m, x, y);  
  29.             if( (c[i]-c[j])%d ) continue;  
  30.             x *= (c[i]-c[j])/d;  
  31.             if(d < 0)   d = -d;  
  32.             x = (x%(m/d) + m/d)%(m/d);  
  33.             // 在两个人都没死之前碰面  
  34.             if(x <= l[i] && x <= l[j])  return false;  
  35.         }  
  36.     }  
  37.     return true;  
  38. }  
  39.   
  40. int main() {  
  41.     int t;  
  42.     scanf("%d", &t);  
  43.     while(t--) {  
  44.         scanf("%d", &n);  
  45.         int ans = 0;  
  46.         for(int i = 0;i < n; i++) {  
  47.             scanf("%d%d%d", &c[i], &p[i], &l[i]);  
  48.             c[i]--;   // 从0开始方便处理  
  49.             ans = max(ans, c[i] + 1);  
  50.         }  
  51.         while(true) {  
  52.             if(solve(ans))  break;  
  53.             ans++;  
  54.         }  
  55.         printf("%d\n", ans);  
  56.     }  
  57.     return 0;  
  58. }  

抱歉!评论已关闭.