Nowcodercontest5278H 纸牌游戏

Nowcodercontest5278H 纸牌游戏

可以合理地想到从高到低依次枚举每一位的数,然后\(\text{Check}\)一下后面是否存在方案,问题在于如何快速Check

设还还剩下的\(\mod 3=0,1,2\)的数个数分别为\(c[0..2]\)

设总共还需要\(n\)个,需要凑出\(\mod 3=t\)的方案

这时后我们假设枚举某一个,比如我们枚举\(0\)选了\(i\)个,设还剩下\(n-i\)个要选,设剩下两个选了\(y,x\)个,则有限制条件

\[x+y=n-i \]

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

\(x\)带掉,得到

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

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

我们可以根据各种限制条件解出\(y\)的可行区间,然后判断区间内是否存在一个\(y\)即可

同时我们可以发现,随\(i\)的增大,\(y\)的可行范围也会增大,所以可以直接枚举最大的3个\(i\)就能完成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);
	}
}


猜你喜欢

转载自www.cnblogs.com/chasedeath/p/12727079.html