CF1759F

  • 因为每次只对原数加 1,所以表示出来所有的数最多需要 p1 次(一共 p 种数字,in[1] 已经被表示出来了)

  • 对于输入数的最低位 in[1],如果有比他小的数没被表示出来,那么一定存在进位(进位过程中,所有大于 in[1] 的数全被表示出来了,进位后 in[1] 变为0),进位需要 (p1)in[1]+1

  • 找到没有被表示出来的最大的数 k表示出来他需要 kin[1]

  • 寻找 “没有被表示出来的最大的数” 时,根据鸽巢原理,范围是上限 limitlimitn

  • 代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
int t;
int n,p,in[101];
map <int,int> rec;
signed main(){
// freopen("1.in","r",stdin);
cin>>t;
while(t--){
cin>>n>>p;
for(int i=1;i<=n;i++){
cin>>in[i];
rec[in[i]]++;
}
int ans=0,limit=p-1; //步数,“没有被表示出来的最大的数” 的上限
bool add=0; //是否需要进位
reverse(in+1,in+1+n); //最低位在前,方便进位
for(int i=in[1];i>=max(in[1]-n,1ll*0);i--){
if(!rec[i]){
add=1; //有比个位小的数没表示出来,需要进位
break;
}
}
if(add){
ans=ans+((p-1)-in[1]+1);
limit=in[1]-1; //进位过程中比in[1]大的数全部被表示出来了,可能的“没有被表示出来的最大的数”最大为in[1]-1
in[1]=0; in[2]++;
for(int i=2;i<=n;i++){
if(in[i]>=p){
in[i+1]=in[i+1]+(in[i]/p);
in[i]%=p;
}
}
for(int i=1;i<=n;i++) //进位后统计是否有新出现的数
rec[in[i]]++;
if(in[n+1]) rec[in[n+1]]++;
}
for(int i=limit;i>=max(limit-n,1ll*0);i--){
if(!rec[i]){
ans=ans+(i-in[1]); //最大的“没有被表示出来的最大的数”
break;
}
}
cout<<ans<<"\n";
rec.clear();
memset(in,0,sizeof(in));
}
}
posted on   Bubble_e  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话



点击右上角即可分享
微信分享提示