荒岛野人

来源:互联网 发布:mysql 索引 编辑:程序博客网 时间:2024/06/02 07:48

Description

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

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

Input

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

Output

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

Sample Input

3 1 3 4 2 7 3 3 2 1

Sample Output
6
Data Constraint
Hint
该样例对应于题目描述中的例子。

分析:

  首先分析两个野人i,j的情况。如果i,j在x年相遇并且在第x年时俩人都活着,则可以得到一个同余方程:
  c[i]+xp[i]=c[j]+xp[j](ModM)
  
  现在我们要求不能使野人们相遇,则需要让这个同余方程无解,或解出的最小的x比两个人中任何一人的寿命长。

上述是两个野人之间的分析,但对于n个野人呢,由于n<=15,我们完全可以双重循环两两判断比较。M的初始值为max{c[i]}(易证,若山洞个数比初始位置还少,是不可行的),每次两两判断时,若有一对能相遇,则这个M不可行,需要M++,直到找到一个M,使每两个野人都不能相遇,则这个M为最终答案。
同余方程:
c[i]+xp[i]c[j]+xp[j](modM)
移项可得:
(p[i]p[j])xc[j]c[i](modM)
即求满足 (p[i]p[j])xMy=c[j]c[i]
的最小的正整数x
其中在每一步,pi-pj已知,M已知,cj-ci已知,方程即转化为ax+by=c,很眼熟吧?用扩展欧几里得就能求出一组可行的(x,y)的解,但是此时的x并不是最小的正整数解,还需借助通解式x=x0+kb来求出最小正整数解.

#include <cstdio>#include <iostream>#include <cmath>#include <cstring>#include <algorithm>#define N 20#define fo(i,a,b) for (int i=a;i<=b;i++)using namespace std;int c[N],p[N],l[N],n;bool bz;int Exgcd(int a,int b,int &x,int &y){    if (!b)     {        x=1;y=0;        return a;    }    int d=Exgcd(b,a%b,x,y);    int t=x;    x=y;    y=t-(a/b)*y;    return d;}bool pd(int x,int i,int j){    bz=true;    if (x<=min(l[i],l[j]))     {        bz=false;        return false;    }    return true;}int main(){    freopen("data.in","r",stdin);    scanf("%d",&n);    int k=0;    fo(i,1,n)    {        scanf("%d%d%d",&c[i],&p[i],&l[i]);        k=max(k,c[i]);    }    if (n==1)    {        printf("%d",1);        return 0;    }    while (true)    {        bz=true;        fo(i,1,n-1)        {            fo(j,i+1,n)            {                int x,y;                int pcha=p[i]-p[j],ccha=c[j]-c[i];                int d=Exgcd(pcha,k,x,y);                if (ccha%d) continue;                int xx=(x*ccha/d)%(k/d);                if (xx<0) xx+=abs(k/d);                if (!pd(xx,i,j)) break;            }            if (!bz) break;        }        if (bz)         {            printf("%d",k);            return 0;        }        k++;    }}
2 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 内地学生赴港签证怎么办 学生去日本旅游签证怎么办 澳洲未婚妻签需要单身证明怎么办 高院收到申诉材料怎么办? 辞职出国留学后社保怎么办 高三数学40来分怎么办 论文查重表格内容重复怎么办 榕树叶子掉光了怎么办 2017江苏高考2c怎么办 高考刚过三本线怎么办 江苏高考选修有d怎么办 西安地铁卡丢了怎么办 酒后头痛怎么办快速缓解疼痛 孕妇感冒头痛怎么办快速缓解疼痛 投稿后发现文章有错误怎么办 如有一方不同意离婚怎么办 孩子上课时注意力不集中怎么办 幼儿上课时注意力不集中怎么办 孩子读初中不爱读书怎么办 老师需要刺激孩子家长怎么办 错觉视界第11关怎么办 爱逃学的学生老师怎么办 论文投稿发现有错误怎么办 孩子上初中数学物理不好怎么办 火山小视频误踢怎么办 铁棍山药弄到手很痒怎么办 山药皮过敏很痒怎么办 貔貅被家人摸了怎么办? 摸了山药很痒怎么办 山药搞得皮肤痒怎么办 手上弄了山药痒怎么办 老板就是个富二代怎么办 中考准考证密码忘了怎么办 准考证号和密码忘了怎么办 安运继续教育考试不及格怎么办 微信的视频打不开怎么办 公众号被取消了怎么办 合同上不写工资怎么办 已经上班了想考个大专文凭怎么办 微信小程序违规暂停服务怎么办 程序锁密码忘了怎么办