C语言实践第二次习题集之旋转骰子

旋转骰子

题目

玛莎有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;
            }
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/031902522ycy/p/12424022.html