11.7多校联考

T1

为了避免晚上种种事情导致写不成题解就先把T1写了,毕竟也是很值得写的。
我这道题凭着一个半感性半理性的想法意外的水到了80分……真的是很考人品啊【学竞赛啊,坠重要的就是人品!】
先看正解:
我们可以这样化:
T=(((sbk1+i1a)bk2+i2a)bk3+i3a)bk4+......
再化简一下:
T=sbk1+...+kn+i1abk2+...+kn+...+inabkn
所以我们可以在最外层枚举 k1+...+kn ,然后把剩余的值/a,开始递归,接着依次枚举 k2+...+kn,k3+...+kn,.....,kn 每次使它们的值尽量大,这样得到的加减次数就会尽量小了。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=1e9;
int s,t,a,b;
int mpow[30];
int solve(int x,int tmp)
{
    if(x==0) return 0;
    for(int i=tmp;i>=0;i--){
        if(mpow[i]>x) continue;
        for(int j=0;;j++){
            if(j*mpow[i]<=x&&(j+1)*mpow[i]>x) {
                int ret=solve(x-j*mpow[i],i);
                if(ret==-1) return -1;
                return ret+j;
            }
        }
    }   
}
int main()
{
    //freopen("a.in","r",stdin);
    //freopen("a.out","w",stdout);
    int ans=inf,cnt=0;
    scanf("%d%d%d%d",&s,&t,&a,&b);
    //T=s*b^(k1+....kn)+i1*a*b^(k2+....kn)+...+in*a*b^kn
    mpow[0]=1;
    for(int i=1;mpow[i-1]<=t;i++,cnt++) mpow[i]=mpow[i-1]*b;
    cnt--;
    for(int i=0;i<=cnt;i++){
        if((t-s*mpow[i])%a==0){
            int ret;
            ret=solve((t-s*mpow[i])/a,i);
            if(ret==-1) continue;
            ans=min(ans,i+ret);
        }
    }
    if(ans==inf) printf("-1");
    else printf("%d",ans);
    return 0;
}

我的那个诡异的方法是怎么回事晚上补

T3
易理解具有二分性质
易理解进行x轮操作,可以把小B的操作全部提到前面。
把每个数指向它应该在的位置,如果形成了一个环,那么环内交换的数一共只用“环内数字-1”
例:1 3 2 5 4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值