标签:start scan 简单 不能 turn 使用 void 开始 转换
玛莎有n个骰子,每个骰子的6个面上都恰好有一个0到9之间的数字。
现在玛莎将利用这n个筛子来制作新数字。她把n个骰子摆成一排,然后从左到右查看骰子的上表面并读取,即可得到一个新数字。随后她不断的旋转每个骰子的面就可以得到不同的新数字。旋转骰子需要满足以下规则:
1、制作的数字不能包含前导零; 2、制作新数字时不需要使用所有的骰子; 3、使用骰子旋转,无法将数字9转换为数字6,反之亦然。
给定n个骰子,玛莎可以用它们构成从1到x的所有整数。玛莎想知道,对于给定的n个骰子,这个x的最大取值是多少呢?
第一行仅一个整数n,表示骰子的数量(1≤n≤3)。
接下来n行,每行包含6个整数a[i][j](0≤a[i][j]≤9),表示第i个骰子的第j个面上的数字。
输出一个整数,即最大数x,玛莎可以使用她的骰子构成数字从1到x。如果无法构成1,则输出0。
3
0 1 3 5 6 8
1 2 4 5 7 8
2 3 4 6 7 9
98
这题思路其实挺简单的,因为1<=n<=3,n的取值不是很大,所以我写了几个特判,手法比较粗暴。另外,n取值较大的话解法还是挺值得思考的。
还有就是这题算是模拟类型的题目吧,有一些常用的技巧,比如设置数组来标记啊啥的。
#include<stdio.h>
void make_num1(int s);//第一类生成函数
void make_num2(int start,int end);//第二类生成函数
void make_num3(int s);//第三类生成函数
int num[3][6],vis[1005];//vis数组用于标记本次生成的数在之前是否已生成过了
int main()
{
int n,i,j;
scanf("%d",&n);
vis[0]=0;//把vis数组初始化
for(i=0;i<3;i++){
for(j=0;j<6;j++){
scanf("%d",&num[i][j]);
}
}
//分层处理
for(i=0;i<n;i++) make_num1(i);//第一类生成函数针对单个骰子的情况
if(n>=2){//n大于等于2时,要开始考虑两个骰子一起组成数字的情况了
make_num2(0,1);
/*这里注意还需考虑骰子的顺序可以颠倒,比如编号为0的骰子
和编号为1的骰子可以从0读取到1,也可从1读取到0*/
make_num2(1,0);
}
if(n==3){
make_num2(1,2);//编号为1和编号为2的骰子
make_num2(2,1);//记得颠倒
make_num2(0,2);//别忘了0号和2号骰子
make_num2(2,0);
make_num3(0);//第三类生成函数
make_num3(-1);//同样也要颠倒,从2号到1号到0号
}
for(i=1;vis[i]!=0;i++) ;//找出第一个未生成数的位置
if(i==1) printf("0");
else printf("%d",i-1);
return 0;
}
void make_num1(int s)
{
int i;
for(i=0;i<6;i++){
if(vis[num[s][i]]==0) vis[num[s][i]]=1;//赋值为1,表示已生成该数
}
}
void make_num2(int start,int end)
{
int i,j,store;
for(i=0;i<6;i++){
for(j=0;j<6;j++){
store=num[start][i]*10+num[end][j];
if(vis[store]==0) vis[store]=1;
}
}
}
void make_num3(int s)
{
int i,j,k,store,s1=2,s2=1,s3=0;//s1,s2,s3在默认情况下设为从0读到1再读到2的顺序
if(s==0){//进行颠倒情形运算的预处理
s1=0;
s2=1;
s3=2;
}
for(i=0;i<6;i++){
for(j=0;j<6;j++){
for(k=0;k<6;k++){
store=num[s1][i]*100+num[s2][j]*10+num[s3][k];
if(vis[store]==0) vis[store]=1;
}
}
}
}
标签:start scan 简单 不能 turn 使用 void 开始 转换
原文地址:https://www.cnblogs.com/031902522ycy/p/12424022.html