codefroces 991F 性质分析

本文探讨了一种算法,用于寻找给定整数n的最大优化表示形式,限制表示法的长度不超过8位。通过分析不同数学操作对位数的影响,确定了有效使用幂运算的策略,并提供了实现这一算法的具体代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目分析

由于n1010n≤1010,所以除了10101010外,其他数都是9位,所以如果我们要更换表示法,这个新表示法应该要小于等于8位。而10101010的最简表示法显然也不会超过8位。

考虑表示法里会有几个加号。发现把一个简单数字(即不带乘号和幂号的项)表示为一个简单数字加一个简单数字的形式,位数一定不会减少,因此加号串联的几个项中,最多有一个项是简单数字,又因为表示法不能超过8位,所以最多用2个加号,并且这三项的长度分别是3,3,1。又因为9^9+9^9+9=774840987并没有减少表示法长度,所以加号最多有一个。

接着发现,一个xx位的简单数字A和一个yy位的简单数字B相乘,结果的位数不会大于x+yx+y。所以一个项也不能写成ABA∗B的形式,因而如果要将nn更换表示法,其中一定有一个幂次表达(即表示法中一定存在a^b的形式。)

那么我们可以把所有能够被幂次表达,且小于n的数及它的最简幂次表达用一个map存一下,这个总共是根号级别的。然后取每一个幂次表达,将其写成C*a^b+D的形式,其中C和D是简单数字或被幂次表达的项,并且C=nabC=⌊nab⌋D=nmodabD=nmodab

这个做法看起来很正确,但是这时候有Lcy发问了,凭什么CCD就是这样取的呢?能不能把CC稍微减小一点,使得C位数减小,并且DD位数不变,使得表示法更优呢?

既然C位数可以减小,说明至少有两位。a和b至少一位,D至少一位,加上三个符号,正好是8位。由于C减小1后,D要变成(D+ab)(D+ab),应该还是1位,所以abab一定是一个一位数。我们发现会发生Lcy提问条件的数nn,都是两位数,根本不需要写成C*a^b+D的形式,所以我们不用考虑这个问题,该做法正确。

代码

注意要用C++17提交,C++11太慢了QAQ

#pragma G++ optimize (2)
#include<bits/stdc++.h>
using namespace std;
#define RI register int
typedef long long LL;
LL n,sqn;string ans;
map<LL,string> mp;
int main()
{
    cin>>n;
    sqn=sqrt(n);
    for(LL i=2;i<=sqn;++i) {
        string ii=to_string(i);
        if(!mp.count(i)||mp[i].length()>ii.length()) mp[i]=ii;
        for(LL j=i*i,k=2;j<=n;j*=i,++k) {
            string kl=ii+"^"+to_string(k);
            if(!mp.count(j)||mp[j].length()>kl.length()) mp[j]=kl;
        }
    }
    ans=to_string(n);
    for(map<LL,string>::iterator it=mp.begin();it!=mp.end();++it) {
        string kl;LL x=(*it).first;
        if(n/x!=1) {
            string y=to_string(n/x);
            if(mp.count(n/x)&&mp[n/x].length()<y.length()) kl+=mp[n/x]+"*";
            else kl+=y+"*";
        }
        kl+=(*it).second;
        if(n%x!=0) {
            string y=to_string(n%x);
            if(mp.count(n%x)&&mp[n%x].length()<y.length()) kl+="+"+mp[n%x];
            else kl+="+"+y;
        }
        if(kl.length()<ans.length()) ans=kl;
    }
    cout<<ans;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值