POJ3101 分数的最小公倍数
这个题怎么说呢?像是高中物理题吧, 选一个W0 = 2*pi/t0,作为参考系, 则Wi=2*pi/ti, Wx = Wi - W0 = 2*pi*(t0-ti)/t0*ti; 则相对半圈时间是tbi = t0*ti/2*(t0-ti); 对于所有的tbi(i>=1), 我们找到一个时间T,使这个时间可以整除所有的tbi, 最后使这个T最小,那么T就是这个答案。根据上面的分析得知我们要求得T就是tbi的最小公倍数。。代码如下:
#include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; int n; int t[1024], r[1000]; int fz[10000 + 100]; int gcd(int a, int b) { if(b==0) return a; else return gcd(b, a%b); } void multi(int d) //高精度乘法 { int tmp = 0; for(int i=0; i<1000; i++) { r[i] = r[i]*d + tmp; tmp = r[i]/10000; r[i] %= 10000; } } int main() { while(scanf("%d", &n) == 1) { memset(fz, 0, sizeof(fz)); for(int i=0; i<n; i++) scanf("%d", &t[i]); sort(t, t+n); n = unique(t, t+n) - t; int fm = 0; for(int i=1; i<n; i++) { int a = t[0]*t[i]; int b = 2*abs(t[0]-t[i]); int c = gcd(a, b); a /= c; b /= c; // a / b fm = gcd(b, fm); for(int i=2; i<10000; i++) { int k = 0; while(a%i == 0) { k++; a/=i; } if(k > fz[i]) fz[i] = k; if(a == 1) break; } } memset(r, 0, sizeof(r)); r[0] = 1; for(int i=2; i<10000; i++) for(int j=0; j<fz[i]; j++) multi(i); int i = 999; while(r[i]==0) i--; printf("%d", r[i]); for(int k=--i; k>=0; k--) printf("%04d", r[k]); //注意高精度输出啊, wa了几发 printf(" "); printf("%d\n", fm); } return 0; }

浙公网安备 33010602011771号