CF1759F题解

Brief Description

给你一个 n 位的 p 进制数,第 i 位为 ai

请问最少要让该数加多少次 1,可以让数码 0,,p1 都出现过(包含在中间过程出现)。

Solution

因为是 p 进制,不难发现答案一定不会超过 p1,也就是说在最坏情况下就是其最后一位加至多 p1 次才可以使得 0,,p1 每一个数码都出现一次。

然而题目给的数有 n 位,是有一定量的数码是出现过的。
所以显然可以考虑分进位不进位分类讨论。

进位的条件其实就是存在小于它的数它没有出现过

这样讨论完了之后假设第一位为 x 那么小于等于 x 的都出现过,那么我们只需要找到一个最大的没有出现过的数让 x 加到这个数就好了。

Code

#include<bits/stdc++.h> using namespace std; const int N = 5e6+5; int a[N]; map<int,bool> vis; int main(){ int t; scanf("%d",&t); while(t--){ int n,p; scanf("%d%d",&n,&p); for(int i=1; i<=n; i++) scanf("%d",&a[i]); for(int i=1; i<=n; i++) vis[a[i]] = true; reverse(a+1,a+n+1); bool flag = true; for(int i=a[1]; i>=max(a[1]-300,0); i--) if(!vis[i]) flag = false; set<int> st; int ans = 0; int limit = p - 1; if(!flag){ ans += p - 1 - a[1] + 1; limit = a[1] - 1;a[1] = 0; a[2]++; for(int i=2; i<=n; i++){ if(a[i] == p) a[i] = 0,a[i+1]++; } } for(int i=1; i<=n; i++) vis[a[i]] = true; if(a[n+1]) vis[a[n+1]] = true; for(int i=limit; i>=max(limit-300,0); i--){ if(!vis[i]){ ans = ans + i - a[1]; break; } } printf("%d\n",ans);vis.clear(); for(int i=1; i<=n+1; i++) a[i] = 0; } return 0; }

__EOF__

本文作者_NightFire666_
本文链接https://www.cnblogs.com/NightFire666-blog/p/18665439.html
关于博主:_NightFire666_
版权声明:转载请注明来源哟~ QAQ
声援博主:UP UP UP !!!
posted @   夜·煞  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示