扩展欧几里得水题

1、nyoj144

思路:根据扩展欧几里得,ax+by=c,当c!=__gcd(a,b)时无整数解

#include<bits/stdc++.h>
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define ll long long
#define ld long double
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lowbit(x) (x&(-x))
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define lcm(a,b) ((a)*(b)/(__gcd((a),(b))))
#define mod 1000000007
#define MP make_pair
#define PI pair<int,int>
#define N putchar('N'),putchar('o'),putchar('\n')
#define Y putchar('Y'),putchar('e'),putchar('s'),putchar('\n')
using namespace std;
//const int N = 1e5 + 100;
ll a, b, d, t;
int main() {
    cin >> t;
    while(t--) {
        scanf("%lld%lld%lld", &a, &b, &d);
        if(d % __gcd(a, b))
            N;//正常输出居然t了!!
        else
            Y;
    }
}

P2421 [NOI2002]荒岛野人

按说洛谷紫题不能说是水题,不过在我学的那个博客里居然归为模板题,,,所以我就放在这了。

solution:d[i],p[i],l[i]表示每个野人所住的初始洞穴编号,每年走过的洞穴数及寿命值。

设在第x年时,(d[i]+p[i]*x)%m!=(d[j]+p[j]*x)%m时才算可以。

所以(d[i]+p[i]*x)%m=(d[j]+p[j]*x)%m比较好算,化为同余方程:(p[i]-p[j])*x+my=d[j]-d[i];

枚举年份看看最大年份。

#include <bits/stdc++.h>
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define ll long long
#define ld long double
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lowbit(x) (x&(-x))
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define lcm(a,b) ((a)*(b)/(__gcd((a),(b))))
#define mod 100003
#define MP make_pair
#define PI pair<int,int>
using namespace std;
const int N = 1e2 + 10;
const int MOD = 1e9 + 7;
int n, d[N], p[N], l[N], s, m, x, y;
int exgcd(int a, int b) {
    if (b == 0) {
        x = 1, y = 0;
        return a;
    }
    int d = exgcd(b, a % b);
    int t = x;
    x = y;
    y = t - a / b * y;
    return d;
}
int check() {
    for(int i = 1; i < n; i++) {
        for(int j = i + 1; j <= n; j++) {
            int a = p[i] - p[j];
            int b = m;
            int c = d[j] - d[i];
            int r = __gcd(a, b);
            if(c % r)
                continue;
            exgcd(a, b);//一定放在下面,算的太慢了,放在上面t了
            b = abs(b / r);
            x = ((x * c / r) % b + b) % b;//求x
            if(x <= min(l[i], l[j]))//看x是否符合寿命
                return 1;
        }
    }
    return 0;
}
int main() {
    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> d[i] >> p[i] >> l[i]; //每个野人所住的初始洞穴编号,每年走过的洞穴数及寿命值。
        s = max(s, d[i]);
    }
    for(m = s; check(); m++);
    cout << m;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Endeavor_G/article/details/88983376