只有1的时候,会出现Impossible; 当输入的数是奇数时,直接输出k k-1,因为,任意个连起来的数相乘都是偶数; 如果是偶数,则枚举的i值到i*i<n,因为下一个就是i*j
(j=i+1),如果i*i>n,就不用枚举了,所以右边界确定下来,时间复杂度其实是O(N^0.5)
#include <iostream> #include <cstdio> using namespace std; int main() { long long n; int i,j; int k; int cases = 1; int ans1,ans2; while(cin>>k){ int flag1 = 0; int flag2 = 0; if(k==1){ printf("Case %d: Impossible",cases++); flag2 = 1; } if(flag2){ cout<<endl; continue; } for(i=2;i*i<k;i++){ //枚举商的起点,1到i-1的乘值是被除数和除数约去的,所以i-1就是除数阶乘之前的值 n=i; for(j=i+1;;j++){ n*=j; if(n==k){ flag1 = 1; ans1=j; ans2=i-1;//1到i-1的乘值是被除数和除数约去的,所以i-1就是除数阶乘之前的值 break; } if(n>k) break; } if(flag1) break; } if(flag1) printf("Case %d: %d %d ",cases++,ans1,ans2); else //因为是双重循环,比如起点为3后,第一次乘的是3*4,其实是4和2的阶乘,也就是说起点被除数和除数都是从相差2开始 printf("Case %d: %d %d ",cases++,k,k-1);//k!/(k-1)!肯定为k,但被除数的值是最大的 } return 0; }