//比较水的数论题,自己想出来的,就写了个题解;
题意是求 2到n之间 n/phi(n) 为最大值时的n;
设 n=(p1^r1)*(p2^r2)*(p3^r3)......(pk*rk);
则 phi(n)=n*(1-1/p1)*(1-1/p2)*......(1-1/pk)
即求 phi(n)/n 为最小时的n;
phi(n)/n=(1-1/p1)*(1-1/p2)*(1-p3)......(1-1/pk);
由此
2=2;
6=2*3;
30=2*3*5;
120=2*3*5*7;
2310=2*3*5*7*11;
......
依次求出 前m个素数的乘积小于10^100;
因此每两个相邻素数(前x个乘积)之间的区间得到的是一个结果;
#include<stdio.h>
#include<string.h>
#define max 110
#define N 300
int s[max][max];
int p[N],mark[N],cnt;
//打出前x个素数乘积<=10^100的素数表;
void prime()
{
int i,j;
cnt=0;
memset(mark,0,sizeof(mark));
for(i=2;i<N;i++)
if(mark[i]==0)
{
p[cnt++]=i;
mark[i]=1;
for(j=i*i;j<N;j+=i)
mark[j]=1;
}
}
//大数相乘,10^100溢出;
void multi(int a[],int k)
{
int i,j,t,tt,x;
int flag=0;
x=p[k];
while(x)
{
t=x%10;
if(t)
for(j=flag,i=0;i<max;i++,j++)
{
tt=s[k][j]+t*a[i];
if(tt>9)
{
s[k][j]=tt%10;
s[k][j+1]+=tt/10;
}
else
s[k][j]=tt;
}
flag++;
x/=10;
}
}
//打表;
void init()
{
int i;
memset(s,0,sizeof(s));
s[0][0]=2;
for(i=1;i<56;i++)
{
multi(s[i-1],i);
}
}
//比较大小;
int cmp(char str[],int s[])
{
int i;
for(i=max-1;i>=0;i--)
if(s[i]>(str[i]-'0'))
return 1;
else if(s[i]<(str[i]-'0'))
return -1;
return 0;
}
int main()
{
int T,i,j,t,len;
char ss[max],str[max];
prime();
init();
scanf("%d",&T);
while(T--)
{
scanf("%s",ss);
len=strlen(ss);
for(j=0,i=len-1;i>=0;i--,j++)
str[j]=ss[i];
for(;j<max;j++)
str[j]='0';
str[j]='\0';
// printf("str=%s\n",str);
for(i=55;i>=0;i--)
if(cmp(str,s[i])<=0)
break;
t=i;
i=max-1;
while(s[t][i]==0)
i--;
for(;i>=0;i--)
printf("%d",s[t][i]);
printf("\n");
}
return 0;
}