bzoj1407

扩展欧几里得

我们发现其实就是两个野人在自己的寿命内不会相遇,或者永远不会相遇,那么我们枚举m,然后枚举两个人,看是否符合条件

扩展欧几里得ax+by=c,这里c不能取模,a能取模,具体不想了

#include<bits/stdc++.h>
using namespace std;
const int N = 20;
int n;
int c[N], p[N], l[N];
void ex_gcd(int a, int b, int &x, int &y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
    }
    else
    {
        ex_gcd(b, a % b, y, x);
        y -= x * (a / b);
    }
}
int main()
{
    scanf("%d", &n);
    int low = 0;
    for(int i = 1; i <= n; ++i) 
    {
        scanf("%d%d%d", &c[i], &p[i], &l[i]);
        low = max(low, c[i]);
    }
    low = max(low, n);
    for(int m = low; m <= 1000000; ++m)
    {
//        printf("m=%d\n", m);
        bool flag = true;
        for(int i = 1; i <= n; ++i)
        {
            for(int j = i + 1; j <= n; ++j)
            {
                int a, b, delta_v = ((p[i] - p[j]) % m + m) % m , delta_d = c[j] - c[i];
                if(delta_v < 0) 
                {
                    delta_v *= -1;
                    delta_d *= -1;
                }
//                delta_d = (delta_d % m + m) % m;
                int t = __gcd(delta_v, m), tmp = m / t;
                if(delta_d % t != 0) continue;
                ex_gcd(delta_v, m, a, b);
                a *= delta_d / t;
                a = (a % tmp + tmp) % tmp;
                if(a <= min(l[i], l[j]))
                {
                    flag = false;
                    break;
                }
            }
            if(!flag) break;
        }
        if(flag) 
        {
            printf("%d\n", m);
            return 0;
        }
    }
    return 0;
}
View Code

 

posted @ 2017-08-10 11:53  19992147  阅读(95)  评论(0编辑  收藏  举报