Codeforces Round #739 (Div. 3)
可能是一開始大佬都寫F1去了,我在D寫完后發現F過的人數比E多了好多(個位數與十位數),以為F1比較簡單,就直接開F1了,但自己分類討論老是考慮不完整,導致罰時直接垮掉
本來已經不想開E了,結果發現延長了15分鍾,嘗試着開一開,結果發現很水……現在在懷疑人生了嗯。
UPD: F2已補
A - Dislike of Threes
思路
數據范圍小(\(k\le 1000\)),暴力預處理后輸出即可。
代碼
// URL: https://codeforces.com/contest/1560/problem/0
// Problem: A. Dislike of Threes
// Contest: Codeforces - Codeforces Round #739 (Div. 3)
// Time Limit: 1000 ms
// Memory Limit: 256 MB
// Author: StelaYuri
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
#define all(a) (a).begin(),(a).end()
#define mst(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-12;
const double PI=acos(-1.0);
const ll mod=998244353;
const int dx[8]={0,1,0,-1,1,1,-1,-1},dy[8]={1,0,-1,0,1,-1,1,-1};
void debug(){cerr<<'\n';}template<typename T,typename... Args>void debug(T x,Args... args){cerr<<"[ "<<x<< " ] , ";debug(args...);}
mt19937 mt19937random(std::chrono::system_clock::now().time_since_epoch().count());
ll getRandom(ll l,ll r){return uniform_int_distribution<ll>(l,r)(mt19937random);}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll qmul(ll a,ll b){ll r=0;while(b){if(b&1)r=(r+a)%mod;b>>=1;a=(a+a)%mod;}return r;}
ll qpow(ll a,ll n){ll r=1;while(n){if(n&1)r=(r*a)%mod;n>>=1;a=(a*a)%mod;}return r;}
ll qpow(ll a,ll n,ll p){ll r=1;while(n){if(n&1)r=(r*a)%p;n>>=1;a=(a*a)%p;}return r;}
vector<int> vec;
int ck(int a)
{
if(a%10==3||a%3==0)return 0;
return 1;
}
void init()
{
int p=1;
while(vec.size()<1000)
{
if(ck(p))
vec.pb(p);
p++;
}
}
void solve()
{
int n;
cin>>n;
cout<<vec[n-1]<<'\n';
}
int main()
{
closeSync;
init();
multiCase
{
solve();
}
return 0;
}
B - Who's Opposite?
思路
根據題意,\(|a-b|\times 2\)可以得出這個環的點數\(n\)
那么兩點在環內相互對視的充分必要條件就是\(a\pm\frac n 2=b\)
最后只需要\(c\le n\),便能得出\(c\)對視的點
代碼
// URL: https://codeforces.com/contest/1560/problem/B
// Problem: B. Who's Opposite?
// Contest: Codeforces - Codeforces Round #739 (Div. 3)
// Time Limit: 1000 ms
// Memory Limit: 256 MB
// Author: StelaYuri
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
#define all(a) (a).begin(),(a).end()
#define mst(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-12;
const double PI=acos(-1.0);
const ll mod=998244353;
const int dx[8]={0,1,0,-1,1,1,-1,-1},dy[8]={1,0,-1,0,1,-1,1,-1};
void debug(){cerr<<'\n';}template<typename T,typename... Args>void debug(T x,Args... args){cerr<<"[ "<<x<< " ] , ";debug(args...);}
mt19937 mt19937random(std::chrono::system_clock::now().time_since_epoch().count());
ll getRandom(ll l,ll r){return uniform_int_distribution<ll>(l,r)(mt19937random);}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll qmul(ll a,ll b){ll r=0;while(b){if(b&1)r=(r+a)%mod;b>>=1;a=(a+a)%mod;}return r;}
ll qpow(ll a,ll n){ll r=1;while(n){if(n&1)r=(r*a)%mod;n>>=1;a=(a*a)%mod;}return r;}
ll qpow(ll a,ll n,ll p){ll r=1;while(n){if(n&1)r=(r*a)%p;n>>=1;a=(a*a)%p;}return r;}
void solve()
{
ll a,b,c;
cin>>a>>b>>c;
if(a>b)
swap(a,b);
ll n=(b-a)*2;
if(b!=(a+n/2-1)%n+1||c>n)
{
cout<<"-1\n";
return;
}
cout<<(c+n/2-1)%n+1<<'\n';
}
int main()
{
closeSync;
multiCase
{
solve();
}
return 0;
}
C - Infinity Table
思路
假設數字\(1\)位於第\(1\)層,數字\(2,3,4\)位於第\(2\)層,……
發現第\(i\)層的數字個數為\(i\times 2-1\)
那么假設當前求的數字\(k\)位於第\(x+1\)層,那么前\(x\)層的總數便是\(x^2\)
由於數字\(k\)比較大,其位於的層數可以直接\(\sqrt {k-1}+1\)得出,或是通過二分得出(二分比較靠譜)
於是我們發現\(k=10^9\)時,其所在層的編號也只有幾萬,並且數據組數\(T\le 100\),所以這里直接上笨方法,循環處理即可
代碼
// URL: https://codeforces.com/contest/1560/problem/C
// Problem: C. Infinity Table
// Contest: Codeforces - Codeforces Round #739 (Div. 3)
// Time Limit: 1000 ms
// Memory Limit: 256 MB
// Author: StelaYuri
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
#define all(a) (a).begin(),(a).end()
#define mst(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-12;
const double PI=acos(-1.0);
const ll mod=998244353;
const int dx[8]={0,1,0,-1,1,1,-1,-1},dy[8]={1,0,-1,0,1,-1,1,-1};
void debug(){cerr<<'\n';}template<typename T,typename... Args>void debug(T x,Args... args){cerr<<"[ "<<x<< " ] , ";debug(args...);}
mt19937 mt19937random(std::chrono::system_clock::now().time_since_epoch().count());
ll getRandom(ll l,ll r){return uniform_int_distribution<ll>(l,r)(mt19937random);}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll qmul(ll a,ll b){ll r=0;while(b){if(b&1)r=(r+a)%mod;b>>=1;a=(a+a)%mod;}return r;}
ll qpow(ll a,ll n){ll r=1;while(n){if(n&1)r=(r*a)%mod;n>>=1;a=(a*a)%mod;}return r;}
ll qpow(ll a,ll n,ll p){ll r=1;while(n){if(n&1)r=(r*a)%p;n>>=1;a=(a*a)%p;}return r;}
void solve()
{
ll k;
cin>>k;
ll l=1,r=100000;
while(l<=r)
{
ll mid=l+r>>1;
ll t=mid*2-1;
ll sum=(1+t)/2*mid;
if(sum<k)
l=mid+1;
else
r=mid-1;
} //二分出k位於第l層,這種二分方式最終狀態為l==r+1
//cout<<r<<' ';
k-=(1+r*2-1)/2*r; //也就是r*r
k--;
int x=1,y=l;
if(k==0)
{
cout<<x<<' '<<y<<'\n';
return;
}
repp(i,1,l)
{
k--;
x++;
if(k==0)
{
cout<<x<<' '<<y<<'\n';
return;
}
}
repp(i,1,l)
{
k--;
y--;
if(k==0)
{
cout<<x<<' '<<y<<'\n';
return;
}
}
}
int main()
{
closeSync;
multiCase
{
solve();
}
return 0;
}
D - Make a Power of Two
思路
做法是先找出與\(2^i\)的前綴相同的最長子序列,那么原長度減去最長子序列長度就是要刪除的字符個數,最后再加上\(2^i\)減去匹配上的前綴后的長度,也就是需要添加的字符個數
例如對於\(1052\),令其與\(2^{10}=1024\)進行匹配,得出與\(1024\)的前綴相同的最長子序列為\(102\),則說明原數字里的\(5\)需要刪除,刪除后需要再加一個\(4\)在末尾才能得到\(1024\)
猜想是對\(i=0\sim 62\)(long long最大值為\(2^{63}-1\))的每個\(2^i\)都做一遍匹配,找最小值就是答案——由於\(2^{62}\)次方已經是一個\(19\)位數,所以這個冪次如果再大也只會徒增刪除次數
代碼
// URL: https://codeforces.com/contest/1560/problem/D
// Problem: D. Make a Power of Two
// Contest: Codeforces - Codeforces Round #739 (Div. 3)
// Time Limit: 1000 ms
// Memory Limit: 256 MB
// Author: StelaYuri
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
#define all(a) (a).begin(),(a).end()
#define mst(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-12;
const double PI=acos(-1.0);
const ll mod=998244353;
const int dx[8]={0,1,0,-1,1,1,-1,-1},dy[8]={1,0,-1,0,1,-1,1,-1};
void debug(){cerr<<'\n';}template<typename T,typename... Args>void debug(T x,Args... args){cerr<<"[ "<<x<< " ] , ";debug(args...);}
mt19937 mt19937random(std::chrono::system_clock::now().time_since_epoch().count());
ll getRandom(ll l,ll r){return uniform_int_distribution<ll>(l,r)(mt19937random);}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll qmul(ll a,ll b){ll r=0;while(b){if(b&1)r=(r+a)%mod;b>>=1;a=(a+a)%mod;}return r;}
ll qpow(ll a,ll n){ll r=1;while(n){if(n&1)r=(r*a)%mod;n>>=1;a=(a*a)%mod;}return r;}
ll qpow(ll a,ll n,ll p){ll r=1;while(n){if(n&1)r=(r*a)%p;n>>=1;a=(a*a)%p;}return r;}
int ar[20],br[20];
int ck(ll a,ll b)
{
int pa=0,pb=0;
while(a) //先按位將a,b倒置在數組中,並求出長度pa,pb
{
ar[pa++]=a%10;
a/=10;
}
while(b)
{
br[pb++]=b%10;
b/=10;
}
int j=pb-1,r=0; //j+1為待添加的數量,r為待刪除的數量
per(i,pa-1,0)
{
if(j>=0&&ar[i]==br[j])
j--;
else
r++;
}
return j+1+r;
}
void solve()
{
int n;
cin>>n;
int ans=INF;
rep(i,0,62)
ans=min(ans,ck(n,1LL<<i));
cout<<ans<<'\n';
}
int main()
{
closeSync;
multiCase
{
solve();
}
return 0;
}
E - Polycarp and String Transformation
思路
發現如果只看每種字符最后一次出現的所在位置,拼接起來后一定就是刪除順序
例如\(haaha\)這個例子,從后往前看,只在每種字符第一次出現時記錄下來(或是從前往后看,只在最后一次出現時記錄),於是得到刪除順序為\(ha\)
於是根據刪除順序,開始檢查是否存在一個原串是按照這個順序操作得到
由題意得,原串一定是給定字符串的某個前綴,並且最小長度是\(\max\{L[ch_i]\}\),其中\(L[ch_i]\)為每種字符第一次出現的位置
由於長度有\(5\times 10^5\),我們沒法枚舉每種長度的前綴,再去\(O(n)\)檢查這個前綴是否合法
但發現,可以在枚舉每種長度的前綴時,只看每種字符出現的次數,模擬刪除順序后便能夠得到最終長度,此時只有在得到的長度與輸入的字符串長度相同時,再去進行\(O(n)\)檢查其合法性,發現這樣只需要\(O(26)\)就可以做完一次粗略的check
代碼
// URL: https://codeforces.com/contest/1560/problem/E
// Problem: E. Polycarp and String Transformation
// Contest: Codeforces - Codeforces Round #739 (Div. 3)
// Time Limit: 3000 ms
// Memory Limit: 256 MB
// Author: StelaYuri
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
#define all(a) (a).begin(),(a).end()
#define mst(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-12;
const double PI=acos(-1.0);
const ll mod=998244353;
const int dx[8]={0,1,0,-1,1,1,-1,-1},dy[8]={1,0,-1,0,1,-1,1,-1};
void debug(){cerr<<'\n';}template<typename T,typename... Args>void debug(T x,Args... args){cerr<<"[ "<<x<< " ] , ";debug(args...);}
mt19937 mt19937random(std::chrono::system_clock::now().time_since_epoch().count());
ll getRandom(ll l,ll r){return uniform_int_distribution<ll>(l,r)(mt19937random);}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll qmul(ll a,ll b){ll r=0;while(b){if(b&1)r=(r+a)%mod;b>>=1;a=(a+a)%mod;}return r;}
ll qpow(ll a,ll n){ll r=1;while(n){if(n&1)r=(r*a)%mod;n>>=1;a=(a*a)%mod;}return r;}
ll qpow(ll a,ll n,ll p){ll r=1;while(n){if(n&1)r=(r*a)%p;n>>=1;a=(a*a)%p;}return r;}
int l[26],r[26];
int vis[26];
int cnt[26];
string s,t;
bool finalcheck(int right)
{
int pos=right+1;
mst(vis,0);
for(char c:t)
{
vis[c-'a']=1; //表示這種字符已經被刪除
rep(i,0,right)
{
if(vis[s[i]-'a']) //如果已經被刪除就跳過
continue;
if(s[i]==s[pos])
{
pos++;
}
else
{
return false;
}
}
}
return true;
}
void solve()
{
cin>>s;
int len=s.size();
mst(vis,0);
t="";
per(i,len-1,0) //從后向前,第一次出現就記錄下這個字符,得到刪除序列t
{
if(!vis[s[i]-'a'])
{
vis[s[i]-'a']=1;
t=s[i]+t;
}
}
mst(l,-1);
mst(r,-1);
repp(i,0,len) //記錄每種字符第一次出現位置與最后一次出現位置
{
if(l[s[i]-'a']==-1)
l[s[i]-'a']=i;
r[s[i]-'a']=i;
}
int st=0;
repp(i,0,26)
{
if(l[i]!=-1) //對於每種出現過的字符,取第一次出現位置的最大值作為原串的最小長度
st=max(st,l[i]);
}
mst(cnt,0);
repp(i,0,st) //記錄前綴每種字符出現的次數
cnt[s[i]-'a']++;
while(st<len)
{
cnt[s[st]-'a']++;
int sum=0;
repp(i,0,26)
sum+=cnt[i]; //第一次是將原串全部拼接上
int r=sum;
for(char c:t)
{
sum-=cnt[c-'a']; //按刪除順序去除該字符的影響
r+=sum; //繼續拼接
}
if(r==len&&finalcheck(st)) //只要長度對的上,再進行最終檢查
{
rep(i,0,st)
cout<<s[i];
cout<<' '<<t<<'\n';
return;
}
st++;
}
cout<<-1<<'\n';
}
int main()
{
closeSync;
multiCase
{
solve();
}
return 0;
}
F1. Nearest Beautiful Number (easy version)
思路
雖然但是,強烈不建議看我的代碼,寫得很亂容易看自閉,看思路即可
另提一點,經solemntee佬提點,二進制枚舉后存起來直接二分答案即可,而我第一發沒有優化T掉了之后就不敢再往這個方向寫了(結果發現\(k\le 2\)時情況確實很少,很可惜),代碼很簡單,可以看看
這里是僅針對\(k\le 2\)的奇怪思路,第三種解法見hard版本
首先判斷輸入的數是否已經滿足條件,如果是直接輸出
對於\(k=1\)的情況,明顯對於\(1\sim 9\)每個數位都做一遍取最小即可
對於\(k=2\)的情況(能討論到這里說明數位上至少有\(3\)種數字)
從高位向低位找,先找出現的第一種數\(a\),再找出第二種數\(b\)
即假設對於\(223314\),得\(a=2,b=3\)
記\(mn=\min(a,b),\ mx=\max(a,b)\)
然后找到按順序出現的第三種數字\(c\):
-
如果\(c\lt mn\),說明從這個位置開始,將后面的數全部設置為\(mn\)時,值最小;
-
如果\(mn\lt c\lt mx\),說明\(c\)位置的數不能換成\(mn\)(會變小),但換成\(mx\)時是符合條件的,並且此時應將低於\(c\)位的所有數位都設置成\(mn\)最優;
-
如果\(c\gt mx\),此時\(c\)將不能修改為\(a,b\)任一個:
- 此時,\(a,b,c\)不同,且\(c\)最大,說明\(b\lt 9\),並且\(a\)是最高位的數位,如果我們要修改出現的數\(a,b\),說明最優操作便是\(b:=b+1\)
- 倘若\(b:=b+1\),那么從原本\(b\)出現的第一個位置的后一個數位開始,都應當設置成\(\min(a,b)\)最優
- 考慮一種特殊情況,原本\(a=b+1\),在執行完\(b:=b+1\)后\(a=b\)成立,此時不應當將后面的數位都設置為\(\min(a,b)\),而是直接設置為\(0\)才是最優
- 還有一種方法,就是從\(c\)位置開始向前尋找最后一個出現\(mn\)的位置,如果將這個\(mn\)改為\(mx\), 說明其后的所有數位都設置為\(mn\)也是個極優解
代碼一(分類討論|別看,只是掛着)
// URL: https://codeforces.com/contest/1560/problem/F1
// Problem: F1. Nearest Beautiful Number (easy version)
// Contest: Codeforces - Codeforces Round #739 (Div. 3)
// Time Limit: 1000 ms
// Memory Limit: 256 MB
// Author: StelaYuri
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
#define all(a) (a).begin(),(a).end()
#define mst(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-12;
const double PI=acos(-1.0);
const ll mod=998244353;
const int dx[8]={0,1,0,-1,1,1,-1,-1},dy[8]={1,0,-1,0,1,-1,1,-1};
void debug(){cerr<<'\n';}template<typename T,typename... Args>void debug(T x,Args... args){cerr<<"[ "<<x<< " ] , ";debug(args...);}
mt19937 mt19937random(std::chrono::system_clock::now().time_since_epoch().count());
ll getRandom(ll l,ll r){return uniform_int_distribution<ll>(l,r)(mt19937random);}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll qmul(ll a,ll b){ll r=0;while(b){if(b&1)r=(r+a)%mod;b>>=1;a=(a+a)%mod;}return r;}
ll qpow(ll a,ll n){ll r=1;while(n){if(n&1)r=(r*a)%mod;n>>=1;a=(a*a)%mod;}return r;}
ll qpow(ll a,ll n,ll p){ll r=1;while(n){if(n&1)r=(r*a)%p;n>>=1;a=(a*a)%p;}return r;}
ll ans;
ll n;
void ck1(int x)
{
ll d=x;
if(d>=n)
{
ans=min(ans,d);
return;
}
rep(i,1,10)
{
d=d*10+x;
if(d>=n)
{
ans=min(ans,d);
return;
}
}
}
int d[15];
void solve()
{
int k;
cin>>n>>k;
bool v[10];
mst(v,false);
int len=0,m=n,t=0;
while(m)
{
int i=m%10;
if(!v[i])
{
v[i]=true;
t++;
}
m/=10;
d[len++]=i;
}
if(t<=k)
{
cout<<n<<'\n';
return;
}
ans=LINF;
if(k==1)
{
rep(i,1,9)
ck1(i);
}
else
{
ans=1;
rep(i,1,len)
ans*=10;
rep(i,1,9)
ck1(i);
int a=d[len-1],b=-1;
per(i,len-2,0)
{
if(d[i]!=a)
{
b=d[i];
int mn=min(a,b),mx=max(a,b);
per(j,i-1,0)
{
if(d[j]!=a&&d[j]!=b)
{
if(mn>d[j])
{
d[j]=mn;
per(k,j-1,0)
d[k]=mn;
ll ansd=0;
per(k,len-1,0)
ansd=ansd*10+d[k];
ans=min(ans,ansd);
cout<<ans<<'\n';
return;
}
else if(mx>d[j])
{
d[j]=mx;
per(k,j-1,0)
d[k]=mn;
ll ansd=0;
per(k,len-1,0)
ansd=ansd*10+d[k];
ans=min(ans,ansd);
cout<<ans<<'\n';
return;
}
else
{
ll ansd=0;
repp(k,j,len)
{
if(d[k]==mn)
{
per(uu,len-1,k+1)
ansd=ansd*10+d[uu];
ansd=ansd*10+mx;
per(uu,k-1,0)
ansd=ansd*10+mn;
ans=min(ans,ansd);
break;
}
}
d[i]++; b++;
mn=min(a,b);
if(a==b)mn=0;
per(k,i-1,0)
d[k]=mn;
ansd=0;
per(k,len-1,0)
ansd=ansd*10+d[k];
ans=min(ans,ansd);
cout<<ans<<'\n';
return;
}
}
}
break;
}
}
}
cout<<ans<<'\n';
}
int main()
{
closeSync;
multiCase
{
solve();
}
return 0;
}
代碼二(二進制枚舉預處理)
#include<bits/stdc++.h>
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
#define all(a) (a).begin(),(a).end()
#define mst(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-12;
const double PI=acos(-1.0);
const ll mod=998244353;
const int dx[8]={0,1,0,-1,1,1,-1,-1},dy[8]={1,0,-1,0,1,-1,1,-1};
void debug(){cerr<<'\n';}template<typename T,typename... Args>void debug(T x,Args... args){cerr<<"[ "<<x<< " ] , ";debug(args...);}
mt19937 mt19937random(std::chrono::system_clock::now().time_since_epoch().count());
ll getRandom(ll l,ll r){return uniform_int_distribution<ll>(l,r)(mt19937random);}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll qmul(ll a,ll b){ll r=0;while(b){if(b&1)r=(r+a)%mod;b>>=1;a=(a+a)%mod;}return r;}
ll qpow(ll a,ll n){ll r=1;while(n){if(n&1)r=(r*a)%mod;n>>=1;a=(a*a)%mod;}return r;}
ll qpow(ll a,ll n,ll p){ll r=1;while(n){if(n&1)r=(r*a)%p;n>>=1;a=(a*a)%p;}return r;}
set<ll> st[2];
void deal(int x,int y)
{
int a[2]={x,y};
rep(bit,1,9)
{
repp(sta,0,1<<bit)
{
int t=0,d=1;
repp(i,0,bit)
{
t+=d*a[sta>>i&1];
d*=10;
}
st[1].insert(t);
}
}
}
void init()
{
st[0].insert(1111111111);
st[1].insert(1000000000);
st[1].insert(1111111111);
rep(i,1,9)
{
int d=i;
st[0].insert(d);
st[1].insert(d);
rep(j,1,8)
{
d=d*10+i;
st[0].insert(d);
st[1].insert(d);
}
}
rep(i,1,9)
deal(0,i);
rep(i,1,9)
rep(j,i+1,9)
deal(i,j);
}
void solve()
{
ll n,k;
cin>>n>>k;
cout<<*st[k-1].lower_bound(n)<<'\n';
}
int main()
{
closeSync;
init();
multiCase
{
solve();
}
return 0;
}
F2 - Nearest Beautiful Number (hard version)
思路
要保證答案盡可能小,於是我們每次固定當前數前\(k\)種數位不變,將第\(k+1\)種數位所在位置的數模擬\(+1\),其后的所有數位只需要置\(0\)即可
由於是直接確定了前\(k\)位數位,所以操作次數應當在百次以內
代碼
// URL: https://codeforces.com/contest/1560/problem/F2
// Problem: F2. Nearest Beautiful Number (hard version)
// Contest: Codeforces - Codeforces Round #739 (Div. 3)
// Time Limit: 1000 ms
// Memory Limit: 256 MB
// Author: StelaYuri
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
#define all(a) (a).begin(),(a).end()
#define mst(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-12;
const double PI=acos(-1.0);
const ll mod=998244353;
const int dx[8]={0,1,0,-1,1,1,-1,-1},dy[8]={1,0,-1,0,1,-1,1,-1};
void debug(){cerr<<'\n';}template<typename T,typename... Args>void debug(T x,Args... args){cerr<<"[ "<<x<< " ] , ";debug(args...);}
mt19937 mt19937random(std::chrono::system_clock::now().time_since_epoch().count());
ll getRandom(ll l,ll r){return uniform_int_distribution<ll>(l,r)(mt19937random);}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll qmul(ll a,ll b){ll r=0;while(b){if(b&1)r=(r+a)%mod;b>>=1;a=(a+a)%mod;}return r;}
ll qpow(ll a,ll n){ll r=1;while(n){if(n&1)r=(r*a)%mod;n>>=1;a=(a*a)%mod;}return r;}
ll qpow(ll a,ll n,ll p){ll r=1;while(n){if(n&1)r=(r*a)%p;n>>=1;a=(a*a)%p;}return r;}
int digits(int x)
{
int r=0;
while(x)
{
r|=1<<(x%10);
x/=10;
}
return __builtin_popcount(r);
}
void solve()
{
int n,k;
cin>>n>>k;
while(digits(n)>k)
{
int m=n/10,t=10;
while(digits(m)>k)
{
m/=10;
t*=10;
}
t/=10;
n/=t;
n++;
n*=t;
}
cout<<n<<'\n';
}
int main()
{
closeSync;
multiCase
{
solve();
}
return 0;
}
https://blog.csdn.net/qq_36394234/article/details/119792892