HDU - 5937 E - Equation(搜索)

Little Ruins is a studious boy, recently he learned addition operation! He was rewarded some number bricks of 11 to 99 and infinity bricks of addition mark '+' and equal mark '='.

Now little Ruins is puzzled by those bricks because he wants to put those bricks into as many different addition equations form x + y = zx+y=z as possible. Each brick can be used at most once and x, y, z are one digit integer.

As Ruins is a beginer of addition operation, xx, yy and zz will be single digit number.

Two addition equations are different if any number of xx, yy and zz is different.

Please help little Ruins to calculate the maximum number of different addition equations.

Input

First line contains an integer TT, which indicates the number of test cases.

Every test case contains one line with nine integers, the i^{th}ith integer indicates the number of bricks of ii.

Limits
1 \leq T \leq 301≤T≤30
0 \leq \text{bricks number of each type} \leq 1000≤bricks number of each type≤100

Output

For every test case, you should output 'Case #x: y', where x indicates the case number and counts from 1 and y is the result.

Sample

InputcopyOutputcopy
 
3 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 0 3 3 0 3 0 0 0 0
 
Case #1: 2 Case #2: 6 Case #3: 2

题意:给你1~9的数的个数,让你求形如x+y=z的柿子的个数(x,y,z都是个位数,任意一个数不同就算是一个不同的柿子)

思路:打表一下可以知道,最终不同的柿子只有36个

然后用结构体记下每个柿子的数还有他们的总数

如果读入的数超过了这些数的个数,那么直接输出36就行

然后我们再进行dfs,找每个柿子能不能选就行了


/*

 .----------------.  .----------------.  .----------------.  .----------------. 
| .--------------. || .--------------. || .--------------. || .--------------. |
| |  ________    | || |  _________   | || | ____    ____ | || |     ____     | |
| | |_   ___ `.  | || | |_   ___  |  | || ||_   \  /   _|| || |   .'    `.   | |
| |   | |   `. \ | || |   | |_  \_|  | || |  |   \/   |  | || |  /  .--.  \  | |
| |   | |    | | | || |   |  _|  _   | || |  | |\  /| |  | || |  | |    | |  | |
| |  _| |___.' / | || |  _| |___/ |  | || | _| |_\/_| |_ | || |  \  `--'  /  | |
| | |________.'  | || | |_________|  | || ||_____||_____|| || |   `.____.'   | |
| |              | || |              | || |              | || |              | |
| '--------------' || '--------------' || '--------------' || '--------------' |
 '----------------'  '----------------'  '----------------'  '----------------'

*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<deque>
#include<cmath>
#include<stack>
#define int long long
#define lowbit(x) x&(-x)
#define PI 3.1415926535
#define endl "\n"
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int gcd(int a,int b) {
	return b? gcd(b,a%b):a;
}
/*
int dx[8]={-2,-2,-1,1,2,2,-1,1};
int dy[8]={-1,1,2,2,1,-1,-2,-2};
int dx[4]={0,-1,0,1};
int dy[4]={-1,0,1,0};
int dx[8]={-1,1,0,0,-1,-1,1,1};
int dy[8]={0,0,-1,1,-1,1,-1,1};
*/
//int e[N],ne[N],h[N],idx,w[N];
/*void add(int a,int b,int c){
	e[idx]=b;
	w[idx]=c;
	ne[idx]=h[a];
	h[a]=idx++;
}
*/
const int N=2e5+10;
int n;
int cnt[12];
int num[12];
int ans;
struct name{
	int x,y,z;
}q[40];
void init(){//记录每个柿子和每个数用了几次
	int op=0;
	for(int i=1;i<=9;i++){
		for(int j=1;j<=9;j++){
			if(i<=9&&j<=9&&i+j<=9){
				cnt[i]++;
				cnt[j]++;
				cnt[i+j]++;
				q[++op]={i,j,i+j};
			}
		}
	}
}
void dfs(int i,int sum){//到第i个柿子选了sum个柿子
	ans=max(sum,ans);
	if(i>36){//如果大于36的话我们就剪枝
		return ;
	}
    if(sum+36-i+1<=ans) return ;//这步是最大值剪枝,当我们选了剩下的所有的柿子之后没超过当前的最大值,那么我们直接返回
	int x=q[i].x ,y=q[i].y ,z=q[i].z ;
	//选第i个柿子
	if(num[x]>0&&num[y]>0&&num[z]>0){//如果当前柿子的个数>0
		num[x]--;
		num[y]--;
		num[z]--;
		if(num[x]>=0 && num[y]>=0 && num[z]>=0)dfs(i+1,sum+1);//如果选了之后他们的个数不是负数,就进入下一个柿子,总数++
		num[x]++;
		num[y]++;
		num[z]++;//回溯
	}
	//不选第i个柿子
	dfs(i+1,sum);
}
signed main(){
	int t;
	init();
	scanf("%d",&t);
	for(int p=1;p<=t;p++){
		for(int i=1;i<=9;i++)scanf("%d",&num[i]);
		bool f=true;
		for(int i=1;i<=9;i++){
			if(num[i]<cnt[i]){
				f=false;
				break;
			}
		}
		if(f){
			printf("Case #%d: %d\n",p,36);
			continue;
		}
		ans=0;
		dfs(1,0);	//从第一个柿子开始,选了0个柿子	
		printf("Case #%d: %d\n",p,ans);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值