xtu oj Dice

题目描述

你有三颗六面的骰子,骰子的每个面上刻有0∼9个点(0个就是没有点),你可以用任意多颗骰子摆成一排,顶部的点数,从左到右组成一个数字,比如三颗骰子的顶部依次为1,0,9点,组成数字109。 你想知道手上的骰子能组成多少种不同的数字?

输入

第一行是一个整数T(1≤T≤1000),表示样例的个数。 每个样例为三行,每行6个数码,表示对应骰子六个面的点数。

输出

每行输出一个样例的结果。

样例输入

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

样例输出

720
810

思路:首先读懂题目,说白了就是三个骰子的骰面数字的排列组合(需要注意的是题目说任意个骰子),考虑重复数字的情况下最多就是1296个组合。考虑到样例最多1000个,因此大概率是可以暴力,不用费脑。

暴力思路就是开一个数组num用来存放所有可能出现的数字,用三个函数计算三种骰子组合带来的所有数字,用哈希表来记录数字重复情况,计算不同的数字个数即可,AC代码如下

#include <stdio.h>
#include <string.h>
int x[7];
int y[7];
int z[7];
int num[10000];
int hash[1500];
int base=0;
void add1(int a[7],int b[7],int c[7])
{
	for(int i=0;i<6;i++)
	{
		for(int j=0;j<6;j++)
		{
			for(int k=0;k<6;k++)
			{
				num[base++]=a[i]*100+b[j]*10+c[k];
			}
		}
	}
 } 
void add2(int a[7],int b[7])
{
	for(int j=0;j<6;j++)
		{
			for(int k=0;k<6;k++)
			{
				num[base++]=a[j]*10+b[k];
			}
		}
}
void add3(int a[7])
{
	for(int i=0;i<6;i++)
	{
		num[base++]=a[i];
	}
}
int main()
{
	int cases;
	scanf("%d",&cases);
	while(cases--)
	{
		memset(hash,0,sizeof(hash));
		base=0;
		for(int i=0;i<6;i++)
		{
			scanf("%d",&x[i]);
		}
		for(int i=0;i<6;i++)
		{
			scanf("%d",&y[i]);
		}
		for(int i=0;i<6;i++)
		{
			scanf("%d",&z[i]);
		}
		add1(x,y,z);
		add1(x,z,y);
		add1(y,x,z);
		add1(y,z,x);
		add1(z,x,y);
		add1(z,y,x);
		add2(x,y);
		add2(y,x);
		add2(y,z);
		add2(x,z);
		add2(z,x);
		add2(z,y);
		add3(x);
		add3(y);
		add3(z);	
		//记录重复元素
		for(int i=0;i<base;i++)
		{
			hash[num[i]]++;
		 } 
		//计数
		int acount=0;
		for(int i=0;i<1500;i++)
		{
			if(hash[i]!=0)
			{
				acount++;
			}
		}
		printf("%d\n",acount);
	}
	return 0;
 } 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值