HDU 4002 Find the maximum(C++大整数实现+打表)

Problem Description

Euler's Totient function, φ (n) [sometimes called the phi function], is used to determine the number of numbers less than n which are relatively prime to n . For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and relatively prime to nine, φ(9)=6. 
HG is the master of X Y. One day HG wants to teachers XY something about Euler's Totient function by a mathematic game. That is HG gives a positive integer N and XY tells his master the value of 2<=n<=N for which φ(n) is a maximum. Soon HG finds that this seems a little easy for XY who is a primer of Lupus, because XY gives the right answer very fast by a small program. So HG makes some changes. For this time XY will tells him the value of 2<=n<=N for which n/φ(n) is a maximum. This time XY meets some difficult because he has no enough knowledge to solve this problem. Now he needs your help.

Input

There are T test cases (1<=T<=50000). For each test case, standard input contains a line with 2 ≤ n ≤ 10^100.

Output

For each test case there should be single line of output answering the question posed above.

Sample Input

2
10
100

Sample Output

6
30

Hint

If the maximum is achieved more than once, we might pick the smallest such n.

题意:给定N,求2~N中n/φ(n) 值最大的n。

对于给定的n/φ(n):

因此我们需要求在n范围内质因子最多的数;

考虑到n的范围有10^100;因此可以将各个质因子相乘打表从而限定左右区间来取得结果;(打表大概60个数就能满足题意)

打表发现,在6之后的每个数都是位数都是独一无二的,用char二维数组将打表的数以字符串的形式存入数组;

特殊考虑2 6的情况,对于之后的每个n:先判断它和当前表内数的长度,当它小于表内数的长度时,说明它比这个数要小一位,输出上一个值;当它等于表内数的长度时,进行字符串的比较判断它和表内数的大小;

打表:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
char s[105];
struct BigInt 
{  
	const static int mod = 10000;  
	const static int DLEN = 4;  
	int a[600],len; 
	BigInt()  
	{   
		memset(a,0,sizeof(a));   
		len = 1;  
	}  
	BigInt(int v)  
	{   
		memset(a,0,sizeof(a));   
		len = 0;   
		do   
		{    
			a[len++] = v%mod;    
			v /= mod;   
		}while(v);  
	}  
	BigInt(const char s[])  
	{   
		memset(a,0,sizeof(a));   
		int L = strlen(s);   
		len = L/DLEN;   
		if(L%DLEN)len++;   
		int index = 0;   
		for(int i = L-1;i >= 0;i -= DLEN)   
		{    
			int t = 0;    
			int k = i - DLEN + 1;    
			if(k < 0)k = 0;    
			for(int j = k;j <= i;j++)t = t*10 + s[j] - '0';    
			a[index++] = t;   
		}  
	}  
	BigInt operator +(const BigInt &b)const  
	{   
		BigInt res;   
		res.len = max(len,b.len);   
		for(int i = 0;i <= res.len;i++)res.a[i] = 0;   
		for(int i = 0;i < res.len;i++)   
		{    
			res.a[i] += ((i < len)?a[i]:0)+((i < b.len)?b.a[i]:0); 
		    res.a[i+1] += res.a[i]/mod;    
			res.a[i] %= mod;   
		}   
		if(res.a[res.len] > 0)res.len++;   
		return res;  
	}  
	BigInt operator *(const BigInt &b)const  
	{   
		BigInt res;   
		for(int i = 0; i < len;i++)   
		{    
			int up = 0;    
			for(int j = 0;j < b.len;j++)    
			{     
				int temp = a[i]*b.a[j] + res.a[i+j] + up;     
				res.a[i+j] = temp%mod;     
				up = temp/mod;  
			}    
			if(up != 0)     
			res.a[i + b.len] = up;   
		}   
		res.len = len + b.len;   
		while(res.a[res.len - 1] == 0 &&res.len > 1)res.len--;   
		return res;  
	}  
	void output()  
	{   
		printf("%d",a[len-1]);   
		for(int i = len-2;i >=0 ;i--)    
		printf("%04d",a[i]);   
//		printf("\n");  
	} 
};



const int N=1000;    
int vis[N+10],prime[N+10];
BigInt res[N+10];      
void IsPrime(){   //埃式筛法打质数表    
     vis[0]=0;vis[1]=0;vis[2]=1;      
     for(int i=3;i<N;i++)      
        vis[i]=(i%2==0?0:1);      
     
      for(int i=3;i<=sqrt(N);i++) {    
       if(vis[i]) {    
         for(int j=i*i;j<=N;j+=2*i)    
                vis[j]=0;    
        }         
                
    }
    
	for(int i=1,j=1;i<=N;i++){
		if(vis[i]) prime[j++]=i;
	}

	for(int i=0;i<=N;i++) res[i]=1;

	for(int i=1;i<=60;i++){
		res[i]=res[i-1]*prime[i];
	}
	for(int i=1;i<=60;i++){
		cout<<"\"";
		res[i].output();
		cout<<"\","<<endl;
		
	}
	
}   

int main(){
	freopen("out.txt","w",stdout);
	IsPrime();
}  
  



题目代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
char s[105];
char table[][110]={
"2",
"6",
"30",
"210",
"2310",
"30030",
"510510",
"9699690",
"223092870",
"6469693230",
"200560490130",
"7420738134810",
"304250263527210",
"13082761331670030",
"614889782588491410",
"32589158477190044730",
"1922760350154212639070",
"117288381359406970983270",
"7858321551080267055879090",
"557940830126698960967415390",
"40729680599249024150621323470",
"3217644767340672907899084554130",
"267064515689275851355624017992790",
"23768741896345550770650537601358310",
"2305567963945518424753102147331756070",
"232862364358497360900063316880507363070",
"23984823528925228172706521638692258396210",
"2566376117594999414479597815340071648394470",
"279734996817854936178276161872067809674997230",
"31610054640417607788145206291543662493274686990",
"4014476939333036189094441199026045136645885247730",
"525896479052627740771371797072411912900610967452630",
"72047817630210000485677936198920432067383702541010310",
"10014646650599190067509233131649940057366334653200433090",
"1492182350939279320058875736615841068547583863326864530410",
"225319534991831177328890236228992001350685163362356544091910",
"35375166993717494840635767087951744212057570647889977422429870",
"5766152219975951659023630035336134306565384015606066319856068810",
"962947420735983927056946215901134429196419130606213075415963491270",
"166589903787325219380851695350896256250980509594874862046961683989710",
"29819592777931214269172453467810429868925511217482600306406141434158090",
"5397346292805549782720214077673687806275517530364350655459511599582614290",
"1030893141925860008499560888835674370998623848299590975192766715520279329390",
"198962376391690981640415251545285153602734402721821058212203976095413910572270",
"39195588149163123383161804554421175259738677336198748467804183290796540382737190",
"7799922041683461553249199106329813876687996789903550945093032474868511536164700810",
"1645783550795210387735581011435590727981167322669649249414629852197255934130751870910",
"367009731827331916465034565550136732339800312955331782619462457039988073311157667212930",
"83311209124804345037562846379881038241134671040860314654617977748077292641632790457335110",
"19078266889580195013601891820992757757219839668357012055907516904309700014933909014729740190",
"4445236185272185438169240794291312557432222642727183809026451438704160103479600800432029464270",
"1062411448280052319722448549835623701226301211611796930357321893850294264731624591303255041960530",
"256041159035492609053110100510385311995538591998443060216114576417920917800321526504084465112487730",
"64266330917908644872330635228106713310880186591609208114244758680898150367880703152525200743234420230"};
int main(){	
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%s",s);
		int l=strlen(s);
		if(l==1){
			if(s[0]<'6'){
				printf("2\n");
			}
			else{
				printf("6\n");
			}
			continue;
		}
	
		for(int i=2;;i++){
			int lt=strlen(table[i]);
			if (l<lt){
				cout<<table[i-1]<<endl;
				break;
			}
			else if(l==lt){
				if(strcmp(s,table[i])!=-1){
					cout<<table[i]<<endl;
				}
				else {
					cout<<table[i-1]<<endl;
				} 
				break;
			}			
		}	
	}
}




第一次用C++大整数的板子。。之前因为接触过Java的BigInteger类所以对板子觉得可有可无= =但是记得好像天梯赛的时候电脑上的Eclipse没有自动修改还是自动填充,所以用起Java来略糟心……毕竟还是C++用的多啊~(想起来CCPC网赛时候被BigInteger类T的一题……以及依旧对Java集合爱不释手啊~)





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值