题目描述
你有三颗六面的骰子,骰子的每个面上刻有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;
}