CF#739-F2 Nearest Beautiful Number (hard version)
Nearest Beautiful Number (hard version)
全局链接: Codeforces Round #739 (Div. 3)
题目大意:
用不大于k种数字,构造出比n大的最小值。
大佬的思路:
我太菜了做不来,学习了大佬的思路,他的代码真的很好看===>大佬传送门
因为要是最小的数,所以从低位到高位遍历,每个数都可能可以变得比他大,变了之后要数一下该位置前面(包括自己)的数字中有多少重复数字。若刚刚好是k,那么就要将其后(不包括自己)的所有书变成最小的数;若不到k,那就全部用0。贪的很漂亮啊!!!
#include<bits/stdc++.h>
using namespace std;
string n;
int k;
int cal(string ss){
set<char> s;//set算不同元素的数量
for(auto c: ss)s.insert(c);
return s.size();
}
string solve(){
cin>>n>>k;
if(cal(n) <= k)return n;//若n的数字种类小于kn就是符合条件的k-beautiful数
int len = n.length();
for(int i = len - 1;i >= 0; i--){//从后往前修改修改的位数越少数字就越小
string tmp = n;//所有的操作都在tmp上做
//修改数字实质上只需要修改一位,将那一位改掉大之后,因为要尽可能小,其后面所有的数字 都改成0或者最小数
for(char j = n[i] + 1;j <= '9'; j++){//j是比现在位大的一位数。
set<char>ck;
tmp[i] = j;
for(int k = 0;k <= i; k++)ck.insert(tmp[k]);
if(cal(tmp.substr(0,i + 1)) > k)continue;//前面的数字种类多于k就要到下一个j去判断
char p = ( cal(tmp.substr(0,i + 1)) == k )? *ck.begin() : '0'; //.begin返回的是地址,要*变成值
for(int k = i + 1; k < len ; k++)tmp[k] = p;
if(stoi(tmp) >= stoi(n))//string to int
return tmp;//经过以上除此if的操作后,若tmp是不小于n的那就是最小的满足条件的数字
}
}
}
int main(){
int T;cin>>T;
while(T--)
cout<<solve()<<"\n";
return 0;
}
笔记:
1、cal函数 用set算不重复的元素数量
2、用 for(auto c : ss) 遍历容器
3、stoi() string直接转int的函数
4、从后到前考虑使得答案最小

浙公网安备 33010602011771号