这题是参照了别人的代码才弄出来的,WA得很惨烈
其方法是求出一个由小到大的连续的素数相乘序列2*3*5*7*11...*x,使得乘积为小于n的这种序列中最大的一个。
#include <iostream>
#include<string>
#include <algorithm>
#define PRIMENUM 700
#define max(a,b) a>b?a:b
using namespace std;
int num[100][120];
char in[120],inn[120];
int len[120];
int prime[150][120];
bool sel[PRIMENUM];//内存溢出的结果,如果这里的值很小,使得prime的空间被溢出的sel占据了
void makeprime()
{
int i,j,k,l;
memset(sel,0,sizeof(sel));
for(i=4;i<PRIMENUM;i+=2)
sel[i]=1;
j=2,i=1;
while(j<PRIMENUM)
{
//prime[i++]=j;
int temp = j;//把j转换成多逐位数表示
l = 0;
while (temp)
{
prime[i][l++] = temp%10;
temp/=10;
}
i++,j++;
while(sel[j]&&j<PRIMENUM)
j++;
k=j*3;
while(k<PRIMENUM){
sel[k]=1;
k+=2*j;
}
}
prime[i][0]=-1;
}
bool cmp(int s)
{
int i;
for (i = len[s]-1;i >= 0 && num[s][i] == in[i]-48;i--);
if (i < 0 || num[s][i] < in[i]-48)
return true;
else
return false;
}
int main()
{
int i,j,k,t,n,c;
makeprime();
memset(num,0,sizeof(num));
num[0][0] = i = len[0] = 1;
c = 0;
do //打表
{
c++;
if(c == 26)
c=26;
for (j = 0;j < 110 && j < len[i-1];j++)
{
for (k = 0;k < 3 ;k++)
{
num[i][j+k] += num[i-1][j] * prime[c][k];
}
}
for (j = 0;j < 110;j++)
{
if(num[i][j] >= 10)
{
num[i][j+1]+=num[i][j]/10;
num[i][j]%=10;
}
}
for (j = 110;num[i][j] == 0 ;j--);
len[i++] = j+1;
} while(len[i-1]<=100);
/*
for(i = 0;len[i] < 101;i++){
for(j = len[i] - 1;j >= 0;j--)
printf("%01d",num[i][j]);
printf("\n");
}*/
cin>>t;
while(t--)
{
scanf("%s",inn);
n = strlen(inn);
for (i = n-1;i >= 0 ;i--)
{
in[n-1-i] = inn[i];
}
for (i = 0;len[i] < n;i++);
while(len[i] == n && cmp(i))//num[i]比输入数值小,继续搜索
i++;
i--;
for(j = len[i] - 1;j >= 0;j--)
printf("%01d",num[i][j]);
printf("\n");
}
return 0;
}