zoukankan      html  css  js  c++  java
  • CSU 1446 Modified LCS 扩展欧几里得

    要死了,这个题竟然做了两天……各种奇葩的错误……

    HNU的12831也是这个题。

    题意:

      给你两个等差数列,求这两个数列的公共元素的数量。

      每个数列按照以下格式给出: N F D(分别表示每个数列的长度,首项,公差)。

    思路:

      先用扩展欧几里得得到两个数列的一个交点,然后求出两个数列的第一个交点。然后分别得到从第一个交点,到末项的可能交点数量。

      假设 F1+K1*D1 = F2+K2*D2 是某一个交点, 移向得到 F1 - F2 = K2*D2 - K1*D1。 由扩展欧几里得定理的结论 x*a + y*b = K*gcd(a, b)。

    所以 只有 F1-F2 = K*gcd(D1, D2) 时 才存在交点。

      并且由此可以求得某一个交点。 然后就是求第一个交点,这个我跪了两天,不想说了 0 0

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <cmath>
     6 #include <algorithm>
     7 #include <string>
     8 #include <queue>
     9 #include <stack>
    10 #include <vector>
    11 #include <map>
    12 #include <set>
    13 #include <functional>
    14 #include <time.h>
    15 
    16 using namespace std;
    17 
    18 typedef long long ll;
    19 
    20 const int INF = 1<<30;
    21 
    22 ll N1, F1, D1, N2, F2, D2;
    23 
    24 ll exgcd(ll a, ll b, ll &x, ll &y) {
    25     if (b==0) {
    26         x = 1; y = 0;
    27         return a;
    28     }
    29     ll res = exgcd(b, a%b, y, x);
    30     y -= x*(a/b);
    31     return res;
    32 }
    33 
    34 ll myAbs(ll x) {
    35     return x>0 ? x : -x;
    36 }
    37 
    38 void input() {
    39     scanf("%lld%lld%lld%lld%lld%lld", &N1, &F1, &D1, &N2, &F2, &D2);
    40 }
    41 
    42 void solve() {
    43     ll x, y;
    44     ll d = exgcd(D1, D2, x, y);
    45     if (0!=(myAbs(F1-F2)%d)) {
    46         puts("0");
    47         return ;
    48     }
    49     ll k = (F1-F2)/d;
    50     ll k1 = -k*x, k2 = k*y;
    51 
    52     ll gg = max(F1, F2); //第一个交点必然大于等于两个起点
    53     ll lcm = D1/d*D2;
    54 
    55     gg = ((F1+k1*D1-gg)%lcm + lcm)%lcm + gg; //求出第一个·交点
    56 
    57     ll f1 = (gg-F1)/D1 + 1; //计算出第一个交点分别在两个数列中的下标
    58     ll f2 = (gg-F2)/D2 + 1;
    59 
    60     ll n1 = (N1-f1+(D2/d))/(D2/d);
    61     ll n2 = (N2-f2+(D1/d))/(D1/d);
    62     ll ans = min(n1, n2);
    63     if (ans<0) ans = 0;
    64     printf("%lld
    ", ans);
    65 }
    66 
    67 int main() {
    68     #ifdef Phantom01
    69         freopen("HNU12831.txt", "r", stdin);
    70     #endif //Phantom01
    71 
    72     int Case;
    73     scanf("%d", &Case);
    74     while (Case--) {
    75         input();
    76         solve();
    77     }
    78 
    79     return 0;
    80 }
    CSU 1446
  • 相关阅读:
    Android学习地址
    Android动画设计源码地址
    chromeWebBrowser之浏览器开发
    win8.1蓝屏解决
    打包应用程序
    win8.1解决鼠标右键反应慢的问题
    Rewrite服务器和robots文件屏蔽动态页面
    第08组 Alpha事后诸葛亮
    第08组 Alpha冲刺(6/6)
    第08组 Alpha冲刺(5/6)
  • 原文地址:https://www.cnblogs.com/Phantom01/p/3860063.html
Copyright © 2011-2022 走看看