hdu 4002

来源:互联网 发布:linux cat显示没有文件 编辑:程序博客网 时间:2024/05/07 19:13

这题是参照了别人的代码才弄出来的,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;
}

原创粉丝点击