zoukankan      html  css  js  c++  java
  • BZOJ1407: [Noi2002]Savage

    1407: [Noi2002]Savage

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 2357  Solved: 1056
    [Submit][Status][Discuss]

    Description

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

    HINT

    Source

    【题解】

    题目中说答案不超过1e6,暗示我们枚举答案。设有m个洞穴,如何判断是否可行?

    对于任意i,j(i≠j0,满足对任意x,有Ci + xPi = Cj + xPj (mod m)无解或x的最小正整数解>min(l[i],l[j])

    枚举i,j,判断即可

    这里前者到求最小正整数解的方法

    对于方程ax + by = c

    设g = gcd(a,b),g | c

    设a' = a/g, b' = b/g, c' = c/g

    转化为a'x + b'y = c'

    用exgcd求a'x + b'y = 1的解

    求得x为x0,于是a'x + b'y = c'中x解集为

    x = x0*c' + kb'/gcd(a', b') = x0 + kb',k∈Z

    若b'为负数,需要把b'变成正数,这样变可行因为只影响y不影响x

    xmin = (x * c' % b' + b') % b'

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 #include <queue>
     7 #include <vector>
     8 #define min(a, b) ((a) < (b) ? (a) : (b))
     9 #define max(a, b) ((a) > (b) ? (a) : (b))
    10 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
    11 inline void swap(int &a, int &b)
    12 {
    13     int tmp = a;a = b;b = tmp;
    14 }
    15 inline void read(int &x)
    16 {
    17     x = 0;char ch = getchar(), c = ch;
    18     while(ch < '0' || ch > '9') c = ch, ch = getchar();
    19     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    20     if(c == '-') x = -x;
    21 }
    22 
    23 const int INF = 0x3f3f3f3f;
    24 const int MAXN = 15;
    25 
    26 int c[MAXN + 5], p[MAXN + 5], l[MAXN + 5], n, ma; 
    27 
    28 void exgcd(int a, int b, int &x, int &y)
    29 {
    30     if(!b){x = 1;y = 0;return;}
    31     exgcd(b, a % b, y, x);
    32     y -= a / b * x;
    33     return;
    34 }
    35 int gcd(int a, int b)
    36 {
    37     return !b ? a : gcd(b, a % b);
    38 }
    39 
    40 bool judge(int m)
    41 {
    42     for(register int i = 1;i <= n;++ i) for(register int j = i + 1;j <= n;++j)
    43     {
    44         //先求方程 (pj - pi)x + my = ci - cj的最小正整数解x
    45         int P = p[j] - p[i], C = c[i] - c[j], g = gcd(P, m), M = m, x = 0, y = 0;
    46         if(C % g != 0) continue;
    47         P /= g, C /= g, M /= g;
    48         exgcd(P, M, x, y);
    49         M = M < 0 ? -M : M;
    50         x = (x * C % M + M) % M;
    51         if(!x) x += M;
    52         if(x <= min(l[i], l[j])) return 0;
    53     }
    54     return 1;
    55 }
    56 
    57 int main()
    58 {
    59     read(n);
    60     for(register int i = 1;i <= n;++ i) read(c[i]), read(p[i]), read(l[i]), ma = max(ma, c[i]);
    61     for(register int i = ma;;++ i)
    62         if(judge(i)){printf("%d", i);return 0;}
    63 } 
    BZOJ1407
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 #include <queue>
     7 #include <vector>
     8 #define min(a, b) ((a) < (b) ? (a) : (b))
     9 #define max(a, b) ((a) > (b) ? (a) : (b))
    10 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
    11 inline void swap(int &a, int &b)
    12 {
    13     int tmp = a;a = b;b = tmp;
    14 }
    15 inline void read(int &x)
    16 {
    17     x = 0;char ch = getchar(), c = ch;
    18     while(ch < '0' || ch > '9') c = ch, ch = getchar();
    19     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    20     if(c == '-') x = -x;
    21 }
    22 
    23 const int INF = 0x3f3f3f3f;
    24 const int MAXN = 15;
    25 
    26 int c[MAXN + 5], p[MAXN + 5], l[MAXN + 5], n, ma; 
    27 
    28 void exgcd(int a, int b, int &x, int &y)
    29 {
    30     if(!b){x = 1;y = 0;return;}
    31     exgcd(b, a % b, y, x);
    32     y -= a / b * x;
    33     return;
    34 }
    35 int gcd(int a, int b)
    36 {
    37     return !b ? a : gcd(b, a % b);
    38 }
    39 
    40 bool judge(int m)
    41 {
    42     for(register int i = 1;i <= n;++ i) for(register int j = i + 1;j <= n;++j)
    43     {
    44         //先求方程 (pj - pi)x + my = ci - cj的最小正整数解x
    45         int P = p[j] - p[i], C = c[i] - c[j], g = gcd(P, m), M = m, x = 0, y = 0;
    46         if(C % g != 0) continue;
    47         P /= g, C /= g, M /= g;
    48         exgcd(P, M, x, y);
    49         M = M < 0 ? -M : M;
    50         x = (x * C % M + M) % M;
    51         if(!x) x += M;
    52         if(x <= min(l[i], l[j])) return 0;
    53     }
    54     return 1;
    55 }
    56 
    57 int main()
    58 {
    59     read(n);
    60     for(register int i = 1;i <= n;++ i) read(c[i]), read(p[i]), read(l[i]), ma = max(ma, c[i]);
    61     for(register int i = ma;;++ i)
    62         if(judge(i)){printf("%d", i);return 0;}
    63 } 
    BZOJ1047
  • 相关阅读:
    nginx 下 bootstrap fa 字体异常问题
    centos7 & mysql
    ssh authentication魔鬼细节--.ssh文件夹权限
    python self introspection
    __getattr__ 与动态属性
    dict.items vs six.iteritems
    django ATOMIC_REQUESTS
    HDU 4309 Seikimatsu Occult Tonneru (状压 + 网络流)
    UVaLive 4064 Magnetic Train Tracks (极角排序)
    UVa 11645 Bits (暴力+组合数学)
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8295325.html
Copyright © 2011-2022 走看看