题目

【题目描述】

克里特岛以野人群居而著称。岛上有排列成环行的M个山洞。这些山洞顺时针编号为1,2,…,M。岛上住着N个野人,一开始依次住在山洞C1,C2,…,CN中,以后每年,第i个野人会沿顺时针向前走Pi个洞住下来。每个野人i有一个寿命值Li,即生存的年数。下面四幅图描述了一个有6个山洞,住有三个野人的岛上前四年的情况。三个野人初始的洞穴编号依次为1,2,3;每年要走过的洞穴数依次为3,7,2;寿命值依次为4,3,1。

奇怪的是,虽然野人有很多,但没有任何两个野人在有生之年处在同一个山洞中,使得小岛一直保持和平与宁静,这让科学家们很是惊奇。他们想知道,至少有多少个山洞,才能维持岛上的和平呢?

【输入】

输入文件的第1行为一个整数N(1<=N<=15),即野人的数目。第2行到第N+1每行为三个整数Ci, Pi, Li (1<=Ci,Pi<=100, 0<=Li<=10^6 ),表示每个野人所住的初始洞穴编号,每年走过的洞穴数及寿命值。

【输出】

输出文件仅包含一个数M,即最少可能的山洞数。输入数据保证有解,且M不大于10^6。

【样例输出】

3

1 3 4

2 7 3

3 2 1

【样例输出】

6

【提示】

该样例对应于题目描述中的例子。


题解

看完题目后,我忍不住吐槽一句——题目好烂!

题目中说野人群居,但是却又让野人单独居住,这还叫群居吗?!

好了,回归正题。这题一看就知道是一道数学题(废话),直接暴力是肯定不行的(废话)。

可以先枚举m,再枚举所有两个野人的情况,看看他们会不会在有生之年相遇在同一个山洞。

前面的枚举很简单,关键在于如何判断。

设野人 i 和野人 j 在第 x 年相遇,那么可以列出同余方程:

\[\begin{aligned}
C_i+P_i\cdot x & \equiv C_j+P_j\cdot x & \text{$(mod\space m)$}\\
C_i+P_i\cdot x & =C_j+P_j\cdot x+my & \text{(转化)}\\
P_i\cdot x-P_j\cdot x & =my+C_j-C_i & \text{(移项)}\\
(P_i-P_j)x-my & =Cj-Ci & \text{(化简)}
\end{aligned}
\]

设\(a=P_i-P_j\),\(b=-m\),\(c=C_j-C_i\),就可以把方程转化成以下形式:

\[\begin{aligned}
ax+by=c
\end{aligned}
\]

怎么样?眼熟吧!这就是扩展GCD

首先,可以在式子两边同时模\(\cfrac{c}{gcd(a,b)}\)(如果c不能整除gcd(a,b),那么方程无整数解,可直接退出),为什么?因为a和b一定是可以整除gcd(a,b)的,所以ax和by也一定可以整除它,ax+by也必定可以。

所以式子就变成了这个样子:

\[\begin{aligned}
ax+by&=gcd(a,b)\\
\because gcd(a,b)&=gcd(b,a\mod b)\\
\therefore ax+by&=bx+(a\mod b)y\\
\end{aligned}
\]

所以我们可以逐步递归下去,直到b=0(看下文)。

继续转换,得

\[\begin{aligned}
ax+by&=bx+(a\mod b)y\\
&=bx+(a-[\frac{a}{b}]b)y\\
&=bx+ay-[\frac{a}{b}]by\\
&=ay+b(x-[\frac{a}{b}]y)
\end{aligned}
\]

其中,[x]表示下取整x

由此,得

\[exgcd(ax+by)=exgcd(ay+b(x-[\frac{a}{b}]y))
\]

然后就可以这样递归下去了。

现在再来谈谈b=0的情况:

当b=0时,式子变成了\(ax=gcd(a,b)\)

显然\(a=gcd(a,b)\)(因为x是整数),即x=1,y=0

以下是扩展GCD的代码:

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

注意:扩展GCD的返回值是gcd(a,b)

由于x可能不是非负的最小解,因此我们要把它处理一下

x=x*cc/d%(b/d);
if(x<0) x+=abs(b/d);

前一句可以让x尽可能地靠近0,后一句可以让x非负。

最后判断一下两个野人可不可以在有生之年相遇,即看看是否\(x\le \min(l_i,l_j)\)

这题就搞定了。


代码

#include<cstdio>
using namespace std;
int c[20],p[20],l[20],x,y;
inline int min(int x,int y){return x<y?x:y;}
inline int max(int x,int y){return x>y?x:y;}
inline int abs(int x){return x<0?0-x:x;}
int exgcd(int a,int b)
{
if(b==0)
{
x=1,y=0;
return a;
}
int d=exgcd(b,a%b),t;
t=x;x=y;y=t-a/b*y;
return d;
}
int main()
{
int n,m=0,i,j,k,d,a,b,cc;
bool bk;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d%d%d",&c[i],&p[i],&l[i]);
m=max(m,c[i]);
}
for(k=m;k<=1e+6;k++)
{
bk=0;
for(i=1;i<n;i++)
{
for(j=i+1;j<=n;j++)
{
a=p[i]-p[j],b=k,cc=c[j]-c[i];
d=exgcd(a,b);
if(cc%d) continue;
x=x*cc/d%(b/d);
if(x<0) x+=abs(b/d);
if(x<=min(l[i],l[j]))
{
bk=1;
break;
}
}
if(bk) break;
}
if(!bk) break;
}
printf("%d\n",k);
return 0;
}

【扩展GCD】荒岛野人的更多相关文章

  1. bzoj1407 / P2421 [NOI2002]荒岛野人(exgcd)

    P2421 [NOI2002]荒岛野人 洞穴数不超过1e6 ---> 枚举 判断每个野人两两之间是否发生冲突:exgcd 假设有$m$个洞穴,某两人(设为1,2)在$t$时刻发生冲突 那么我们可 ...

  2. P1516 青蛙的约会和P2421 [NOI2002]荒岛野人

    洛谷 P1516 青蛙的约会 . 算是手推了一次数论题,以前做的都是看题解,虽然这题很水而且还交了5次才过... 求解方程\(x+am\equiv y+an \pmod l\)中,\(a\)的最小整数 ...

  3. UESTC 288 青蛙的约会 扩展GCD

    设两只青蛙跳了t步,则此时A的坐标:x+mt,B的坐标:y+nt.要使的他们在同一点,则要满足: x+mt - (y+nt) = kL (p是整数) 化成: (n-m)t + kL = x-y (L ...

  4. Poj 1061 青蛙的约会(扩展GCD)

    题目链接:http://poj.org/problem?id=1061 解题报告:两只青蛙在地球的同一条纬度线上,选取一个点位坐标轴原点,所以现在他们都在同一个首尾相连的坐标轴上,那么他们现在的位置分 ...

  5. poj 1061 青蛙的约会(扩展gcd)

    题目链接 题意:两只青蛙从数轴正方向跑,给出各自所在位置, 和数轴长度,和各自一次跳跃的步数,问最少多少步能相遇. 分析:(x+m*t) - (y+n*t) = p * L;(t是跳的次数,L是a青蛙 ...

  6. 2014年百度之星程序设计大赛 - 初赛(第一轮) hdu Grids (卡特兰数 大数除法取余 扩展gcd)

    题目链接 分析:打表以后就能发现时卡特兰数, 但是有除法取余. f[i] = f[i-1]*(4*i - 2)/(i+1); 看了一下网上的题解,照着题解写了下面的代码,不过还是不明白,为什么用扩展g ...

  7. BZOJ_2242_[SDOI2011]计算器_快速幂+扩展GCD+BSGS

    BZOJ_2242_[SDOI2011]计算器_快速幂+扩展GCD+BSGS 题意: 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p, ...

  8. 扩展gcd算法

    扩展gcd算法 神tm ×度搜索exgcd 打到exg的时候出来ex咖喱棒... 球方程\(ax+by=\gcd(a,b)\)的一个解 如果\(b=0\),那么\(\gcd(a,b)=a\),取\(x ...

  9. 扩展gcd codevs 1200 同余方程

    codevs 1200 同余方程 2012年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 求关 ...

随机推荐

  1. bk复面-一场被问蒙蔽了的面试

    1.自我介绍         ---自我介绍从个人生活上.兴趣爱好上去介绍,比如我自己,平时喜欢听听音乐.看看鸡汤类的书,比如爱下厨,喜欢根据一些网上的教程去尝试做一份自己满意的晚餐,简历上已经写得工 ...

  2. Jmeter(九)参数化

    参数化是自动化测试脚本的一种常用技巧.简单来说,参数化的一般用法就是将脚本中的某些输入使用参数来代替,在脚本运行时指定参数的取值范围和规则: 这样,脚本在运行时就可以根据需要选取不同的参数值作为输入. ...

  3. 也谈Tcp/Ip协议

    一. 计算机网络体系结构分层 一图看完本文 计算机网络体系结构分层 计算机网络体系结构分层 不难看出,TCP/IP 与 OSI 在分层模块上稍有区别.OSI 参考模型注重“通信协议必要的功能是什么”, ...

  4. [CSP-S模拟测试]:Weed(线段树)

    题目描述 $duyege$的电脑上面已经长草了,经过辨认上面有金坷垃的痕迹.为了查出真相,$duyege$准备修好电脑之后再进行一次金坷垃的模拟实验.电脑上面有若干层金坷垃,每次只能在上面撒上一层高度 ...

  5. [CSP-S模拟测试]:答题(meet in the middle)

    题目传送门(内部题142) 输入格式 输入文件的第一行为两个数$n,P$. 接下来一行$n$为个正整数,表示每道题的分数. 输出格式 输出一行一个正整数,为至少需要获得的分数. 样例 样例输入: 2 ...

  6. Android学习_7/26

    四种基本布局 1. 线性布局(LinearLayout) android:layout_gravity:指定控件在布局中的对齐方式 android:gravity:指定文字在控件中的对齐方式 andr ...

  7. linux shell 值coredump suid_dumpable和 gdb解析coredump文件

    可以设置产生coredump文件,设置dump文件命名非格式,生成dump文件的路径: linux # set suid_dumpable on if [ -e /proc/sys/kernel/su ...

  8. linux如何模糊查找一个文件

    在当前目录下搜索指定文件: find . -name test.txt 在当前目录下模糊搜索文件: find . -name '*.txt' 在当前目录下搜索特定属性的文件: find . -amin ...

  9. HNOI2012排队

    排列组合题(本文A(n,m)表示从n个元素里选m个的排列数). 首先,老师和女生有不能相邻的限制条件,应该用插空法.而且老师人数较少且固定,把老师和男生进行混合,对女生用插空. 我先来一手错误做法,n ...

  10. springboot中如何启动tomcat

    springboot启动时,会自动识别出当前环境是否是web环境还是非web环境. 默认的web环境的context(DEFAULT_WEB_CONTEXT_CLASS):org.springfram ...