Nowcodercontest5278H card game

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

\[x+y=n-i \]

\ [2x + y = t \ (\ mod 3) \]

Take \ (x \) away and get

\ [2n-2i-2y + y = t (\ mod 3) \]

\ [y = 2n-2i-t (\ mod 3) \]

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);
	}
}


Guess you like

Origin www.cnblogs.com/chasedeath/p/12727079.html