列表

详情


NC205301. 纸牌游戏

描述

Cubercsl 和 Oneday 在玩一个纸牌游戏。两个人手中都有 n 张数字牌,每张牌面上都包含 其中一个阿拉伯数字。
游戏规则是需要将手中的牌选出恰好 k 张,组成一个能被 3 整除的非负整数(不能含有多余前导零),组成的数大的获胜。
Cubercsl 自然是想取得胜利,所以他需要找到符合条件的最大的数。

输入描述

第一行包含一个整数 T (),表示测试数据的组数。
对于每组测试数据,包含一个数字构成的串 s () 和一个整数 k (),中间以空格分隔,分别表示 Cubercsl 手中的牌和要选出的牌的数量。
输入保证

输出描述

对于每组测试数据,在一行输出一个整数,表示最大的能被 3 整除的数。特别地,如果无解,输出 -1。

示例1

输入:

9
998244353 1
998244353 2
998244353 3
998244353 4
998244353 5
998244353 6
998244353 7
998244353 8
998244353 9

输出:

9
99
993
9984
99852
998544
9985443
99854433
-1

示例2

输入:

5
99999999999999999999 1
99999999999999999999 2
99999999999999999999 3
99999999999999999999 4
99999999999999999999 5

输出:

9
99
999
9999
99999

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 48ms, 内存消耗: 1736K, 提交时间: 2020-04-20 13:26:04

#include<bits/stdc++.h>
using namespace std;
int _,n,m,a[15],b[15],ans[15];
string s;
bool check(){
	int i;
	for (i=9;i>=0;i--){
		if (b[i]>ans[i]) return 1;
		if (b[i]<ans[i]) return 0;
	}
	return 0;
}
void dfs(int x,int y,int z){
	int i,r;
	if (x<0){
		if (!y&&!z&&check()) memcpy(ans,b,sizeof(b));
		return;
	}
	r=min(z,a[x]);
	if (!x&&z==m) r=min(r,1);
	for (i=max(0,r-2);i<=r;i++){
		b[x]=i;
		dfs(x-1,(y+x*i)%3,z-i);
	}
}
int main(){
	int i,j;
	for (scanf("%d",&_);_;_--){
		cin>>s>>m;
		n=s.length();
		memset(a,0,sizeof(a));
		for (i=0;i<n;i++) a[s[i]-48]++;
		memset(ans,0,sizeof(ans));
		ans[0]=-1;
		dfs(9,0,m);
		if (ans[0]>=0){
			for (i=9;i>=0;i--)
			for (j=1;j<=ans[i];j++) putchar(i+48);
			putchar('\n');
		}
		else printf("-1\n");
	}
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 54ms, 内存消耗: 1620K, 提交时间: 2020-07-04 02:03:32

#include<bits/stdc++.h>
using namespace std;

int i,flag,n,T,V[10],ans[10];
char R[100005];
void DFS(int L,int mod,int s)
{
	int i,j=min(V[L],n-s);
	if(flag)return;
	if(s==n)
	{
		if(!mod)
		{
			for(i=9;i>=0;i--)while(ans[i]--)printf("%d",i);
	        printf("\n");
	        flag=1;
		}
		return;
	}
	if((!L&&!s&&n!=1)||L==-1)return;
	for(i=j;i>=max(0,j-2);i--)ans[L]=i,DFS(L-1,(mod+L*i)%3,s+i),ans[L]=0;
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%s%d",R,&n);
		memset(V,0,sizeof(V)),memset(ans,0,sizeof(ans));
		for(i=0;R[i]!='\0';i++)V[R[i]-'0']++;
		flag=0,DFS(9,0,0);
		if(flag)continue;
		printf("-1\n");
	}
    return 0;
}

上一题