• Savage(扩展欧几里得)


    Savage

    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
    //该样例对应于题目描述中的例子。

    题解:
    由于洞穴是环状的,所以联想到mod。
    看到答案不超过1e6,所以可以从小到大枚举ans,看看每个ans是否合法,如果合法就直接输出。
    首先如果没有寿命的限制,那我们可以列出同余方程ci+pi*x≡cj+pj*x(mod ans)(1<=i,j<=n),如果合法的话,说明x是无解的。
    但是题目中每个人寿命,所以要做一些改变,也就是说当ans合法的时候不仅有上面那个同余方程无解,也可以解出来的x>min(li,lj)

    代码如下

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    int n,c[20],p[20],l[20],ax;
    void exgcd(int a,int b,int &g,int &x,int &y){
        if (!b) g=a,x=1,y=0;
        else exgcd(b,a%b,g,y,x),y-=x*(a/b);
    }
    bool pd(int A){
        for (int i=1;i<=n;i++) for (int j=i+1;j<=n;j++){
            int a=((p[i]-p[j])%A+A)%A,b=((c[j]-c[i])%A+A)%A,x,y,G,F;
            exgcd(a,A,G,x,y);if (b%G) continue;b/=G;F=A/G;
            x=(b*x%F+F)%F;if (x<=l[i] && x<=l[j]) return 0;
        }
        return 1;
    }
    int main(){
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d%d%d",&c[i],&p[i],&l[i]),ax=max(c[i],ax);
        for (int i=ax;;i++) if (pd(i)) {printf("%d
    ",i);return 0;}
        return 0;
    }
  • 相关阅读:
    (3.4)常用知识-char与varchar的选择
    (3.3)常用知识-索引使用、维护与填充因子
    (3.2)常用知识-字符串处理
    (3.1)常用知识-日期处理
    基于Sql Server 2008的分布式数据库的实践
    将expression转化为数据类型int时发生算术溢出错误
    webserver and application server
    web前端
    linkin
    jquery load
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/10544734.html
Copyright © 2020-2023  润新知