Nowcodercontest5278H card game
It is reasonable to think of enumerating the numbers of each digit in order from high to low, and then \ (\ text {Check} \) to see if there is a solution behind, the problem is how to quickly check
Let the number of remaining \ (\ mod 3 = 0,1,2 \) be \ (c [0..2] \)
Suppose a total of \ (n \) is needed , and a plan of \ (\ mod 3 = t \) needs to be made
After a certain time we assume enumeration, for example, we enumerate \ (0 \) chose \ (i \) a, set left \ (ni \) one to choose, let the remaining two chose \ ( y, x \) , there are restrictions
Take \ (x \) away and get
We can solve in accordance with various restrictions \ (Y \) feasible interval, then the interval is determined whether there is a \ (Y \) to
At the same time, we can find that with the increase of \ (i \) , the feasible range of \ (y \) will also increase, so we can directly enumerate the largest three \ (i \) to complete the check
#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;
#define reg register
typedef long long ll;
#define rep(i,a,b) for(reg int i=a,i##end=b;i<=i##end;++i)
#define drep(i,a,b) for(reg int i=a,i##end=b;i>=i##end;--i)
#define pb push_back
template <class T> inline void cmin(T &a,T b){ ((a>b)&&(a=b)); }
template <class T> inline void cmax(T &a,T b){ ((a<b)&&(a=b)); }
char IO;
template<class T=int> T rd(){
T s=0;
int f=0;
while(!isdigit(IO=getchar())) if(IO=='-') f=1;
do s=(s<<1)+(s<<3)+(IO^'0');
while(isdigit(IO=getchar()));
return f?-s:s;
}
const int N=1e5+10;
int n,m;
char s[N],ans[N];
int cnt[10],c[3];
int Check(int n,int t){
rep(i,0,2) c[i]=0;
rep(i,0,9) c[i%3]+=cnt[i];
// x+y=n-i
// x<=c[2] ,y<=c[1]
// 2x+y=t (mod 3)
// x=n-i-y
// 2n-2i-2y+y=t(mod 3)
// 2n-y-2i=t(mod 3)
// y=2n-2i-t (mod 3)
int l0=max(0,n-c[1]-c[2]),r0=min(n,c[0]);
drep(i,r0,max(l0,r0-4)) {
int y=2*n-2*i-t;
y=(y%3+3)%3;
int l=max(0,n-i-c[2]),r=min(c[1],n-i); // y=的可行范围
while(l%3!=y) l++;
if(l<=r) return 1;
}
return 0;
}
int main(){
rep(kase,1,rd()) {
scanf("%s",s+1),n=strlen(s+1),m=rd();
rep(i,0,9) cnt[i]=0;
rep(i,1,n) cnt[s[i]-'0']++;
int fl=1,c=0;
rep(i,1,m) {
ans[i]=0;
drep(j,9,0) if(cnt[j]) {
cnt[j]--;
int t=3-c-j;
t=(t%3+3)%3;
int fl=Check(m-i,t);
if(fl) {
ans[i]=j+'0';
c=(c+j)%3;
break;
}
cnt[j]++;
}
if(!ans[i] || (i==1 && m>1 && ans[i]=='0') ) {
fl=0;
break;
}
}
ans[m+1]=0;
puts(!fl?"-1":ans+1);
}
}