[搜索 剪枝] BZOJ3085 反质数加强版SAPGAP

%%% http://www.cnblogs.com/jianglangcaijin/p/4158422.html


SAPGAP=Super AntiPrime, Greatest AntiPrime


思路:




#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define clr(x,y) memset(x,y,sizeof(x))
using namespace std;
typedef long long ll;

struct BIGINT
{
    int a[27];
  
    BIGINT(){}
    BIGINT(char *s)
    {
        clr(a,0);
        int i,L=strlen(s),cur=0;
        for(i=L-1;i-3>=0;i-=4)
        {
            a[cur]=(s[i-3]-'0')*1000+
                   (s[i-2]-'0')*100+
                   (s[i-1]-'0')*10+
                   (s[i]-'0');
            cur++;
        }
        if(i<0) return;
        if(i==0) a[cur]=s[0]-'0';
        else if(i==1) a[cur]=10*(s[0]-'0')+(s[1]-'0');
        else if(i==2) a[cur]=100*(s[0]-'0')+10*(s[1]-'0')+(s[2]-'0');
    }
    BIGINT(int x)
    {
        clr(a,0);
        a[0]=x;
    }
  
    inline BIGINT operator*(int x)
    {
        int i;
        BIGINT tmp;
        for(i=0;i<27;i++) tmp.a[i]=a[i]*x;
        for(i=0;i<26;i++)
        {
            tmp.a[i+1]+=tmp.a[i]/10000;
            tmp.a[i]%=10000;
        }
        return tmp;
    }
  
    int operator<(BIGINT p)
    {
        int i;
        for(i=26;i>=0;i--)
        {
            if(a[i]<p.a[i]) return 1;
            if(a[i]>p.a[i]) return 0;
        }
        return 0;
    }
  
    int operator==(BIGINT p)
    {
        int i;
        for(i=26;i>=0;i--)
        {
            if(a[i]!=p.a[i]) return 0;
        }
        return 1;
    }
    int operator<=(BIGINT p)
    {
        return *this==p||*this<p;
    }
  
    void print()
    {
        int cur=26;
        while(cur>0&&0==a[cur]) cur--;
        printf("%d",a[cur]);
        cur--;
        while(cur>=0) printf("%04d",a[cur--]);
        puts("");
    }
};

int prime[]=
{
    1,  2,  3,  5,  7,
    11, 13, 17, 19, 23,
    29, 31, 37, 41, 43,
    47, 53, 59, 61, 67,
    71, 73, 79, 83, 89,
    97, 101,103,107,109,
    113,127,131,137,139,
    149,151,157,163,167,
    173,179,181,191,193,
    197,199,211,223,227,
    229,233,239,241,251
};
int K[]=
{
    1,2,2,3,3,
    4,4,5,5,5,
    5,5,6,6,6,
    6,6,6,6,7,
    7,7,7,7,7,
    7,7,7,7,7,
    7,7,8,8,8,
    8,8,8,8,8,
    8,8,8,8,8,
    8,8,8,8,8,
    8,8,8,8,8
};

BIGINT n,ans;
ll m,q1;
ll maximum;

inline void dfs(int k,BIGINT now,ll cnt,ll last)
{
	if(cnt>maximum || cnt==maximum&&now<ans)
    {
        ans=now;
        maximum=cnt;
    }
	if (k!=1)
		last=min(last,q1/(K[k]-1));
	ll tmp=cnt;
	for (int i=1;i<=last;i++)
	{
		if (k==1) q1=i;
		tmp+=cnt;
		now=now*prime[k];
		if (n<now) break;
		dfs(k+1,now,tmp,i);
	}
}

char s[105];

int main()
{
	freopen("t.in","r",stdin);
	freopen("t.out","w",stdout);
	scanf("%s",s);
	n=BIGINT(s);
	if(n==BIGINT(1))
		return printf("1\n"),0;
	BIGINT itmp=BIGINT(1);
	for (;itmp<=n;) itmp=itmp*prime[++m];
	dfs(1,BIGINT(1),1,2*K[m]-1-1);
	ans.print();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值