GCD相关

板子:

1 int gcd(int a, int b) { return b > 0 ? gcd(b, a % b) : a; }

POJ1930

题意:给你一个无限循环小数,给到小数点后 9 位,要求这个数的分数形式。

解法:

要想解决这道题,首先应该了解如何将循环小数化为分数:

一,纯循环小数化分数:循环节的数字除以循环节的位数个 9 组成的整数。例如: 
$0.3333……=3/9=1/3$;
$0.285714285714……=285714/999999=2/7$. 
二,混循环小数:(例如:$0.24333333……$)不循环部分和循环节构成的的数减去不循环部分的差,再除以循环节位数个 9 添上不循环部分的位数个  0。例如: 
$0.24333333…………=(243-24)/900=73/300 $
$0.9545454…………=(954-9)/990=945/990=21/22$

这便是循环小数化成分数的方法,知道这个后,解决这道题也好办了。

代码如下:

  1 #pragma GCC optimize(3)
  2 #include <time.h>
  3 #include <algorithm>
  4 #include <bitset>
  5 #include <cctype>
  6 #include <cmath>
  7 #include <cstdio>
  8 #include <cstdlib>
  9 #include <cstring>
 10 #include <deque>
 11 #include <functional>
 12 #include <iostream>
 13 #include <map>
 14 #include <queue>
 15 #include <set>
 16 #include <sstream>
 17 #include <stack>
 18 #include <string>
 19 #include <utility>
 20 #include <vector>
 21 using namespace std;
 22 const double EPS = 1e-9;
 23 const int INF = 2147483647;
 24 const long long LLINF = 9223372036854775807;
 25 const double PI = acos(-1.0);
 26 
 27 inline int READ() {
 28     char ch;
 29     while ((ch = getchar()) < 48 || 57 < ch)
 30         ;
 31     int ans = ch - 48;
 32     while (48 <= (ch = getchar()) && ch <= 57)
 33         ans = (ans << 3) + (ans << 1) + ch - 48;
 34     return ans;
 35 }
 36 
 37 #define REP(i, a, b) for (int i = (a); i <= (b); i++)
 38 #define PER(i, a, b) for (int i = (a); i >= (b); i--)
 39 #define FOREACH(i, t) for (typeof(t.begin()) i = t.begin(); i != t.end(); i++)
 40 #define MP(x, y) make_pair(x, y)
 41 #define PB(x) push_back(x)
 42 #define SET(a) memset(a, -1, sizeof(a))
 43 #define CLR(a) memset(a, 0, sizeof(a))
 44 #define MEM(a, x) memset(a, x, sizeof(a))
 45 #define ALL(x) begin(x), end(x)
 46 #define LL long long
 47 #define Lson (index * 2)
 48 #define Rson (index * 2 + 1)
 49 #define pii pair<int, int>
 50 #define pll pair<LL, LL>
 51 #define MOD ((int)1000000007)
 52 #define MAXN 20 + 5
 53 ///**********************************START*********************************///
 54 string ss, sn;
 55 
 56 char s[MAXN], ns[MAXN];
 57 int nex[MAXN];
 58 
 59 void get_next(char* p, int next[]) {
 60     int pLen = strlen(p) + 1;  //要求循环节长度时这里才+1
 61     next[0] = -1;
 62     int k = -1;
 63     int j = 0;
 64     while (j < pLen - 1) {
 65         if (k == -1 || p[j] == p[k]) {
 66             ++j;
 67             ++k;
 68             if (p[j] != p[k])
 69                 next[j] = k;
 70             else
 71                 next[j] = next[k];
 72         } else {
 73             k = next[k];
 74         }
 75     }
 76 }
 77 
 78 int gcd(int a, int b) { return b > 0 ? gcd(b, a % b) : a; }
 79 
 80 void cal_cal(int len) {
 81     int up = 0, down = 0;
 82     for (int i = len - 1; i >= 0; i--)
 83         up += int(s[i] - '0') * pow(10, len - i - 1);
 84     for (int i = 0; i < len; i++) down += 9 * pow(10, i);
 85     int g = gcd(up, down);
 86     printf("%d/%d
", up / g, down / g);
 87     return;
 88 }
 89 
 90 void cal_cal2(int st, int len) {
 91     char tmp[20];
 92     int up = 0, down = 0;
 93     int a, b;
 94 
 95     for (int i = 0; i < st; i++) tmp[i] = s[i];
 96     tmp[st] = '';
 97     a = atoi(tmp);
 98     for (int i = st; i < st + len; i++) tmp[i - st] = s[i];
 99     tmp[len] = '';
100     b = atoi(tmp);
101 
102     up = a * pow(10, len) + b - a;
103     int pos = 0;
104     for (int i = 0; i < len; i++) tmp[pos++] = '9';
105     for (int i = 0; i < st; i++) tmp[pos++] = '0';
106     down = atoi(tmp);
107     int g = gcd(up, down);
108     printf("%d/%d
", up / g, down / g);
109     return;
110 }
111 
112 int main() {
113 #ifndef ONLINE_JUDGE
114     freopen("input.txt", "r", stdin);
115 #endif  // !ONLINE_JUDGE
116     while (cin >> ss) {
117         if (ss.size() == 1) break;
118         int pos = 0;
119         for (int i = 2; ss[i] != '.'; i++) s[pos++] = ss[i];
120         s[pos] = '';
121         int flag = 0;  // 1为全循环,2为混合循环
122         get_next(s, nex);
123         int len = pos - nex[pos];
124         if (len != pos) {
125             cal_cal(len);
126         } else {
127             int st;
128             for (st = 1; st < pos; st++) {
129                 int nlen = 0;
130                 for (int i = st; i < pos; i++) {
131                     ns[nlen++] = s[i];
132                 }
133                 CLR(nex);
134                 get_next(ns, nex);
135                 if (nlen - nex[nlen] != nlen) {
136                     cal_cal2(st, nlen);
137                     break;
138                 } else
139                     continue;
140             }
141         }
142     }
143     return 0;
144 }
原文地址:https://www.cnblogs.com/romaLzhih/p/11492993.html