• [noi2002]荒岛野人 拓展欧几里得


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

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

    枚举最小年份,然后判断此年份是否可行;

    如何判断可行,只要两个野人有生之年都不会在一个洞里住,那么就可行;

    枚举i,j野人,得ci-cj=(pj-pi)*x+ky      x表示会相遇的年份;

    若无解,说明不会碰到;

    否则用ex_gcd求出一个解,然后根据这个解求出x的最小正整数解,与min(l[i],l[j])比较一下,即可判断;

    我犯的主要错误是,算出一个x后,x=x*(c[i]-c[j])/d,x=(x%k+k)%k,这里的k应换成k/d,这是由于x+k*t固然是它的解集,但是由于k和p[j]-p[i]之间还有一些公因数,所以漏掉了一些情况,所以计算之前先将k/d,这样就不会再wa了;

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<cstdlib>
     6 #include<ctime>
     7 #include<vector>
     8 #include<algorithm>
     9 #include<queue>
    10 #include<map>
    11 using namespace std;
    12 #define LL long long
    13 const int maxn=20;
    14 void gcd(int a,int b,int &d,int &x,int &y){
    15     if(b==0){d=a;x=1;y=0;return;}
    16     gcd(b,a%b,d,x,y);
    17     int t=x;
    18     x=y;
    19     y=t-a/b*x;
    20 }
    21 int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
    22 int c[maxn],p[maxn],l[maxn],n,Left=0;
    23 void init(){
    24     cin>>n;
    25     for(int i=1;i<=n;i++){cin>>c[i]>>p[i]>>l[i];Left=max(Left,c[i]);}
    26     int x,y,d,kl;
    27     for(int k=Left;k<=1000000;k++){
    28         bool flag=0;
    29         for(int i=1;i<=n;i++)
    30             for(int j=i+1;j<=n;j++){
    31                 if(flag)break;
    32                 gcd(p[j]-p[i],k,d,x,y);
    33                 if((c[i]-c[j])%d)continue;
    34                 x=x*(c[i]-c[j])/d;
    35                 kl=k/d;
    36                 x=(x%kl+kl)%kl;
    37                 if(x<=l[i]&&x<=l[j])flag=1;
    38             }
    39         if(!flag){printf("%d
    %d
    ",k,clock());return;}
    40     }
    41 }
    42 int main(){
    43     freopen("1.in","r",stdin);
    44     freopen("1.out","w",stdout);
    45     init();
    46     return 0;
    47 }
    View Code

    其实我更想吐槽把10^6,弄成106的事情,即使一般有经验的人都不会被坑;

  • 相关阅读:
    了解大数据的特点、来源与数据呈现方式
    结对项目
    第四次作业
    阅读《构建之法》1-5章有感
    iOS 应用如何完全支持 IPv6-ONLY 网络?
    丙申年把真假美猴王囚禁在容器中跑 ASP.NET Core 1.0
    ASP.NET Core 1.0 部署 HTTPS (.NET Framework 4.5.1)
    推荐一款跨平台的 Azure Storage Explorer
    更改 Skype for Business Online 的 Sip 地址以匹配UPN
    C# 计算字符串在控制台中的显示长度
  • 原文地址:https://www.cnblogs.com/chadinblog/p/5879362.html
Copyright © 2020-2023  润新知