题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1407

题意:

有n个野人,野人各自住在第c[i]个山洞中(山洞成环状),每年向前走p[i]个山洞,到这个山洞住下来。

每个野人的寿命为l[i],问至少需要多少个山洞,才能让野人在有生之年永远不住在同一个山洞。

题解:

原本不会拓展欧几里得和同余方程,在这里尽量详细地写一下由这题学到的东西。

我原本是从网上看各类题解然后打的,因为不理解和某些题解上的错误,导致调了很久。

下面写我的题解,如有错误,敬请指出。

设山洞的数量为m。

首先,对于n=2时,若相遇,则得同余方程 c[i]+x*p[i] = c[j]+x*p[j] (mod m)

移项,得:(p[i]-p[j])*x=c[j]-c[i] (mod m)

即:(p[i]-p[j])*x + m*y = c[j]-c[i]

则由于p[i]-p[j]、m、c[j]-c[i]已知,该方程相当于 a*x+b*y=c,可用拓展欧几里得求解。

若该方程无解,或x小于l[i]且x小于l[j](注意是并且的关系,因为一个死了一个活着也是不能相遇的),则不会相遇。

所以,由于n<=15,可以从max(c[i])开始枚举m(因为开始时野人都不在同一个山洞,max(c[i])一定大于等于n),两两匹配,若都不能相遇,则当前的m值为最小整数解。

相关: 用拓展欧几里德算法求不定方程 a*x + b*y = c:

推荐一篇很好的博文:http://www.cnblogs.com/Rinyo/archive/2012/11/25/2787419.html

如果c不是gcd(a,b)的倍数,则该方程无解。

证明:

设g=gcd(a,b),则a=a'g,b=b'g

ax+by=c可化为g(a'x+b'y)=c

由于g、(a'x+b'y)、c都是整数,所以c必然是g的倍数。

拓展欧几里得:

int exgcd(int a,int b)
{
if (b == ) { x=,y=; return a; }
int t = exgcd (b,a%b,x,y);
int x0 = x , y0 = y;
x = y0; y = x0-(a/b)*y0;
return t;
}

证明:

ax + by = gcd(a,b)

bx'+(a%b)y'=gcd(b,a%b)

因为gcd(a,b) = gcd(b,a%b)

所以ax+by = bx'+(a%b)y'

代入a%b =  a - ⌊a/b⌋*b (⌊⌋是向下取整符号)

ax + by = bx' + (a - ⌊a/b⌋*b)y'

ax + by = ay' + b(x'-⌊a/b⌋y')

所以: x = y'  y = x'-⌊a/b⌋*y'

回溯即可得出答案。

此处求出的x和y是一组可行解,可以利用通式

x = x' + k*b

y = y'  - k*a

求出最小整数解。

注意:ax + by = c 求的是c是gcd(a,b)的倍数时的解。

方法一:

方程两边同时除以g

a'=a/g   b'=b/g   c'=c/g

得a'x+b'y=c'

用拓展欧几里德算法求解a'x'+b'y'=1

则 x = x'*c'  y = y'*c'

这时,在用通式求最小整数解时加减的应是b'

方法二:

我们可以直接求出ax’ + by’ =gcd(a,b)

则 x = x'*c/g   y = y' * c/g

这时应注意,在求通式求最小整数解加减的仍应是b/g。(注意!)

代码如下:

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std; const int N=,M=;
int n;
int cc[N],p[N],l[N]; int maxx(int x,int y) {return x>y ? x:y;}
int minn(int x,int y) {return x<y ? x:y;}
int myabs(int x) {return x> ? x:-x;} int gcd(int a,int b)
{
if(b==) return a;
return gcd(b,a%b);
} void exgcd(int a,int b,int &x,int &y)
{
if(b==) {x=,y=;return ;}
exgcd(b,a%b,x,y);
int x0=x,y0=y;
x=y0;y=x0-(a/b)*y0;
return ;
} bool check(int m)
{
for(int i=;i<=n-;i++)
for(int j=i+;j<=n;j++)
{
int a=p[i]-p[j];
int b=m;
int c=cc[j]-cc[i]; int g=gcd(a,b);
if(c%g) continue;
a/=g;b/=g;c/=g;//b在此处可能变为负
int x,y;
exgcd(a,b,x,y);
x=x*c;y=y*c;
while(x>) x-=myabs(b);
while(x<=) x+=myabs(b);
if(x<=minn(l[i],l[j])) return ;//
}
return ;
} int main()
{
scanf("%d",&n);
int mx=n;
for(int i=;i<=n;i++)
{
scanf("%d%d%d",&cc[i],&p[i],&l[i]);
mx=maxx(mx,cc[i]);
}
for(int i=mx;i<=M;i++)
{
if(check(i)) {printf("%d\n",i);break;}
}
return ;
}

【lydsy1407】拓展欧几里得求解不定方程+同余方程的更多相关文章

  1. POJ - 2142 The Balance(扩展欧几里得求解不定方程)

    d.用2种砝码,质量分别为a和b,称出质量为d的物品.求所用的砝码总数量最小(x+y最小),并且总质量最小(ax+by最小). s.扩展欧几里得求解不定方程. 设ax+by=d. 题意说不定方程一定有 ...

  2. POJ.2142 The Balance (拓展欧几里得)

    POJ.2142 The Balance (拓展欧几里得) 题意分析 现有2种质量为a克与b克的砝码,求最少 分别用多少个(同时总质量也最小)砝码,使得能称出c克的物品. 设两种砝码分别有x个与y个, ...

  3. HDU-3579-Hello Kiki (利用拓展欧几里得求同余方程组)

    设 ans 为满足前 n - 1个同余方程的解,lcm是前n - 1个同余方程模的最小公倍数,求前n个同余方程组的解的过程如下: ①设lcm * x + ans为前n个同余方程组的解,lcm * x ...

  4. Looooops(求解同余方程、同余方程用法)【拓展欧几里得】

    Looooops(点击) A Compiler Mystery: We are given a C-language style for loop of type for (variable = A; ...

  5. ACM数论-欧几里得与拓展欧几里得

    ACM数论——欧几里得与拓展欧几里得 欧几里得算法: 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd ...

  6. BZOJ-1407 Savage 枚举+拓展欧几里得(+中国剩余定理??)

    zky学长实力ACM赛制测试,和 大新闻(YveH) 和 华莱士(hjxcpg) 组队...2h 10T,开始 分工我搞A,大新闻B,华莱士C,于是开搞: 然而第一题巨鬼畜,想了40min发现似乎不可 ...

  7. [zoj 3774]Power of Fibonacci 数论(二次剩余 拓展欧几里得 等比数列求和)

    Power of Fibonacci Time Limit: 5 Seconds      Memory Limit: 65536 KB In mathematics, Fibonacci numbe ...

  8. [POJ2115]C Looooops 拓展欧几里得

    原题入口 这个题要找到本身的模型就行了 a+c*x=b(mod 2k) ->  c*x+2k*y=b-a 求这个方程对于x,y有没有整数解. 这个只要学过拓展欧几里得(好像有的叫扩展欧几里德QA ...

  9. 51 Nod 1256 乘法逆元(数论:拓展欧几里得)

    1256 乘法逆元  基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 给出2个数M和N(M < N),且M与N互质,找出一个数K满足0 < K ...

随机推荐

  1. php5.4以上运行yii框架出现问题的解决方法

    Ubuntu Server 下安装 Mcrypt Php Extension http://blog.archean.me/2013/10/22/install-mcrypt-php-extensio ...

  2. Android蓝牙开发浅谈(转)

    http://www.eoeandroid.com/thread-18993-1-1.html 对于一般的软件开发人员来说,蓝牙是很少用到的,尤其是Android的蓝牙开发,国内的例子很少     A ...

  3. C#命名参数

    文章:史上最全的ASP.NET MVC路由配置,以后RouteConfig再弄不懂神仙都难救你啦~ 命名参数规范+匿名对象 routes.MapRoute(name: "Default&qu ...

  4. centos7 下pycharm无法输入中文问题解决方案

    作者使用的pycharm是2017.2 在pycharm.sh脚本的如下行(大约在201行): # -------------------------------------------------- ...

  5. dev_queue_xmit 发生了什么?skb还会在哪里缓存

    见 codebox/net/qdisk/xmit.log中保存了一份记录 调用关系 sch_direct_xmit --> dev_hard_start_xmit --> xmit_one ...

  6. Mysql查询优化从入门到跑路(一)数据库与关系代数

    1.怎样才算是数据库?     ACID,是指在数据库管理系统中事务所具有的四个特性     1)原子性     2)一致性     3)隔离性     4)持久性       关系数据库,基于关系代 ...

  7. 如何用grep命令同时显示匹配行上下的n行 (美团面试题目)

    标准unix/linux下的grep通过以下参数控制上下文 grep -C 5 foo file 显示file文件中匹配foo字串那行以及上下5行grep -B 5 foo file 显示foo及前5 ...

  8. matlab isfield

    isfield 函数功能:判断输入是否是结构体数组的域(成员). 调用格式: tf=isfield(S,'fieldname') 检查结构体S是否包含由fieldname指定的域,如果包含,返回逻辑1 ...

  9. 【题解】HNOI2016网络

    整体二分是个好东西!可我忘记了它QAQ其实当你知道这题可以整体二分的时候就已经不难了(个人觉得这是最难想到的一点啊).整体二分的话,我们就可以把问题转化为是否有一条权值 \(>= k\) 的链经 ...

  10. [洛谷P4721]【模板】分治 FFT_求逆

    题目大意:给定长度为$n-1$的数组$g_{[1,n)}$,求$f_{[0,n)}$,要求: $$f_i=\sum_{j=1}^if_{i-j}g_j\\f_0=1$$ 题解:分治$FFT$博客,发现 ...