题目:
Description
输入两个正整数 n, m,输出 n!/m!,其中阶乘定义为 n!= 1*2*3*...*n (n>=1)。 比如,若 n=6, m=3,则n!/m!=6!/3!=720/6=120。
是不是很简单?现在让我们把问题反过来:输入 k=n!/m!,找到这样的整数二元组(n,m) (n>m>=1)。
如果答案不唯一,n 应该尽量小。比如,若 k=120,输出应该是 n=5, m=1,而不是 n=6, m=3,因为 5!/1!=6!/3!=120,而5<6。
Input
Output
Sample Input
120 1 210
Sample Output
Case 1: 5 1 Case 2: Impossible Case 3: 7 4
这个题目,我加了一个数组list,记录了从0到11的阶乘。
用这个可以减少一些运算,因为如果k=n!/m!,那么一定有(n-m)! | k
代码:
#include<iostream> #include<stdio.h> using namespace std; int list[12] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800 }; bool ok(int n, int k,int l) { long long r = l; for (int i = 1; i < k; i++) { r *= l + i; if (r>n)return false; } return true; } int f(int n, int k) { if (n%list[k])return -1; long long low = 2, high = n / 2; while (low < high-1) { int mid = (low + high) / 2; if (ok(n, k, mid))low = mid; else high = mid; } int r = low; for (int i = 1; i < k; i++)r *= low + i; if (r == n)return low; return -1; } int main() { int cas = 1; int n; while (scanf("%d",&n)!=EOF) { cout << "Case " << cas++ << ": "; if (n == 1)cout << "Impossible"; else { int r = 1234567890, key = 0; for (int k = 2; k <= 11; k++) { int t = f(n, k); if (t>0 && r > t) { r = t; key = k; } } if (r < 1234567890)cout << key + r - 1 << " " << r - 1; else cout << n << " " << n - 1; } cout << endl; } return 0; }
今天又遇到这个题目了,只好又写了一遍。
代码:
#include<iostream> using namespace std; int fac[13] = { 0,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600 }; int n, m, k; bool ok(int low, int len) { long long pi = 1; for (int i = 0; i < len; i++) { pi *= low + i; if (pi > k)return false; } return true; } void f() { n = k; m = k - 1; for (int i = 2; i <= 12; i++) { if (k%fac[i])return; int low = 2, high = k, mid; while (low < high-1) { mid = (low + high) / 2; if (ok(mid, i))low = mid; else high = mid; } int pi = 1; for (int j = 0; j < i; j++)pi *= low + j; if (pi == k) { n = low + i - 1; m = low - 1; } } } int main() { int cas = 1; while (cin >> k) { cout << "Case " << cas++ << ": "; if (k == 1) { cout << "Impossible" << endl; continue; } f(); cout << n << " " << m << endl; } return 0; }