浏览代码

利用周期性求解递推式

zj 5 年之前
父节点
当前提交
842f8cddde
共有 1 个文件被更改,包括 21 次插入34 次删除
  1. 21 34
      G.cpp

+ 21 - 34
G.cpp

@@ -1,46 +1,33 @@
 #include<bits/stdc++.h>
 
 using namespace std;
-int a, b, n;
-int flag[67] = {
-        0
-};
-//mod7 很有意思,最多有 7 * 7种情况吧,找循环结构
-// 十位数是本位,个位数是上一位,方便操作
-int f[100] = {
-        0
-};
+
 
 int main() {
-    while (scanf("%d%d%d", &a, &b, &n)) {
-        int Begin = 100;
-        int length = 0;
-        memset(flag, 0, sizeof(flag));
-        memset(f, 0, sizeof(f));
-        if (a == 0 && b == 0 && n == 0) {
-            break;
+    for (int a, b, n; cin >> a >> b >> n;) {
+        if (a == 0 && b == 0 && n == 0)break;
+        a %= 7, b %= 7;
+        int v[200] = {0, 1, 1};
+        for (int i = 3; i < 200; i++) {
+            v[i] = (v[i - 1] * a + v[i - 2] * b) % 7;
         }
-        f[1] = 1;
-        f[2] = 1;
-        for (int i = 3; i <= 100; i++) {
-            if (i < Begin) {
-                int ans = ((a * f[i - 1] + b * f[i - 2]) % 7) * 10 + f[i - 1];
-                if (flag[ans] == 0) {
-                    flag[ans] = i;
-                } else {
-                    Begin = flag[ans];
-                    length = i - flag[ans];
+
+        int left, right, period;
+        for (int i = 1; i < 99; i++) {
+            int x = v[i], y = v[i + 1];
+            for (int k = i + 2; k < 99; k++) {
+                if (v[k] == x && v[k + 1] == y) {
+                    left = i;
+                    right = k;
+                    period = right - left;
+                    break;
                 }
-                f[i] = ans / 10;
-            } else {
-                break;
             }
         }
-        if (n < Begin) {
-            printf("%d\n", f[n]);
-        } else {
-            printf("%d\n", f[(n - Begin) % length + Begin]);
-        }
+        // copy(v,v+200,ostream_iterator<int>(cout,""));cout<<endl;
+        //cout<<"left="<<left<<",period="<<period<<endl;
+        n = n % period + period;
+        cout << v[n] << endl;
     }
     return 0;
 }