• 一本通1637荒岛野人


    1637:荒岛野人

    Description

    Input

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

    Output

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

    Sample Input

    3
    1 3 4
    2 7 3
    3 2 1

    Sample Output

    6

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

    sol:感觉挺难的,想了好久吧。。

    原式:
    C[i]+k*P[i] = C[j]+k*P[j] (%Mod)
    使得该式的解k无解或k>min(L[i],L[j])

    转化
    C[i]+k*P[i] = C[j]+k*P[j] (%Mod)
    k*(P[i]-P[j]) = C[j]-C[i] (%Mod)
    k*(P[i]-P[j])+x*Mod = C[j]-C[i] (类ax+by=c的形式) (要求的是k和x)

    然后暴力枚举答案,n2判断即可

    Ps:实现的时候有个细节要注意,式子里的k不能是0,

    /*
    原式: 
    C[i]+k*P[i] = C[j]+k*P[j] (%Mod)
    使得该式的解k无解或k>min(L[i],L[j])
    
    转化
    C[i]+k*P[i] = C[j]+k*P[j] (%Mod)
    k*(P[i]-P[j]) = C[j]-C[i] (%Mod)
    k*(P[i]-P[j])+x*Mod = C[j]-C[i] (类ax+by=c的形式) (要求的是k和x)
    */
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-'); ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-'); x=-x;
        }
        if(x<10)
        {
            putchar(x+'0'); return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    /*
        k*(P[i]-P[j])+x*Mod = C[j]-C[i]
    */
    const int N=20;
    int n,C[N],P[N],L[N];
    inline ll gcd(ll x,ll y)
    {
        return (!y)?(x):(gcd(y,x%y));
    }
    inline void Exgcd(ll a,ll b,ll &X,ll &Y)
    {
        if(b==0)
        {
            X=1;
            Y=0;
            return;
        }
        Exgcd(b,a%b,X,Y);
        ll XX=X,YY=Y;
        X=YY;
        Y=XX-a/b*YY;
        return;
    }
    inline bool Solve(ll Mod)
    {
        int i,j;
        for(i=1;i<n;i++)
        {
            for(j=i+1;j<=n;j++)
            {
                ll a=P[i]-P[j],b=Mod,c=C[j]-C[i];
                ll r=gcd(a,b),X,Y;
                if(c%r==0) // 无解挺好的 
                {
                    Exgcd(a,b,X=0,Y=0);
                    X=X/r*c;
                    ll tmp=abs(b/r);
                    X=(X%tmp+tmp)%tmp;
                    if(!X) X+=tmp;
                    if(X<=min(L[i],L[j])) return 0;
                }
            }
        }
        return 1;
    }
    int main()
    {
        int i,m;
        R(n);
        for(i=1;i<=n;i++)
        {
            R(C[i]); R(P[i]); R(L[i]);
            m=max(m,C[i]);
        }
        for(i=m;;i++)
        {
            if(Solve(i))
            {
                Wl(i); break;
            }
        }
        return 0;
    }
    /*
    input
    3
    1 3 4
    2 7 3
    3 2 1
    output
    6
    */
    View Code
  • 相关阅读:
    【转载】在Linux中使用VS Code编译调试C++项目
    【转载】Visual Studio 2015 for Linux更好地支持Linux下的开发
    【转载】ODBC, OLEDB, ADO, ADO.Net的演化简史
    【转载】OLE DB, ADO, ODBC关系与区别
    【转载】ADO,OLEDB,ODBC,DAO的区别
    【转载】Linux系统启动流程
    91. Decode Ways
    90. Subsets II
    89. Gray Code
    88. Merge Sorted Array
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/10474001.html
Copyright © 2020-2023  润新知