这道题别看是1e5的范围,看起来用两个for循环会超时,但是在n/i*j<j的情况下,break,就会大大减少时间复杂度,还有一个比较坑的点,在代码里有提到
#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <sstream> #include <map> #include <set> #include <queue> #include <stdlib.h> typedef long long ll; using namespace std; int a[100000]; int main() { for (int i=1;i<=10000;i++) { a[i]=i; } int T; cin >> T; while(T--) { int n; cin >> n; //输入要拆分的数 int flag=0,x=0,y=0; int min1=n; //记录c-a的最小值 for(int i=2;i<=n;i++) //i代表的是a { for(int j=2;j<=n;j++) //j代表的是b //这里j要从2开始算,如果从i开始算,当i=100000,则j=100000,那么i*j会爆int,所以要从2开始算,没爆int之前就会break,当然这里直接用long long算也可以。如果从i开始,又没用long long,会发生浮点错误 { if((n%(i*j))==0 && n/(i*j)>=j && i<=j) { int h=n/(i*j); //h代表的是c flag=1; if(h-i<=min1) //如果c-a的值可以更新,记录下a,b的值(已知a,b的值,就可以推出c的值) { x=i; y=j; min1=h-i; } } if((n/(i*j))<j) break; //减少时间复杂度,一但这种情况发生,当前i下面的j也不用遍历了,直接进入下一个i } } if(flag==1) printf("%d=%d*%d*%d\n",n,x,y,n/(x*y)); else printf("No solution\n"); } return 0; }