一、问题描述
液晶数码管用七笔阿拉数字表示的十个数字,把横和竖的一 个短划都称为一笔,即7有3笔,8有7笔等。对于十个数字一种排列,要做到两相邻数字都可以由另一个数字加上几笔或减去几笔组成,但不能又加又减。比如 7→3是允许的,7→2不允许。任意输入一组数,判断是否符合上述规则,注意,1在右边。
二、问题分析
可以联想到我们离散数学课堂上学到的无相关系矩阵,7->3是允许的,则(7,3)(3,7)的值就是1,而7->2是不允许的,则(7,2)(2,7)的值就是0。以此类推写出一个10*10的关系矩阵。这样在判断相邻的数字的时候直接最为坐标进行比较就可以了。
三、算法分析
算法的核心是写出10*10的矩阵
录入数字找到相应的坐标,如果是1,则说明可以这么变换,如果是0则说明不可以这样的变换。返回相应的数字,这里进行判断,如果返回的是0则立刻输出NO并且停止循环,如果是1,则返回数字进行累加,达到数组长度的,就是符合要求,输出YES。同时也可以定义一个指标变量,当指标变量不是数组长度的时候就是NO
四、详细设计(从算法到程序)
(一)定义关系矩阵
int st[10][10]={1,1,0,0,0,0,0,1,1,0,
1,1,0,1,1,0,0,1,1,1,
0,0,1,0,0,0,1,0,1,0,
0,1,0,1,0,0,0,1,1,1,
0,1,0,0,1,0,0,0,1,1,
0,0,0,0,0,1,1,0,1,1,
0,0,1,0,0,1,1,0,1,0,
1,1,0,1,0,0,0,1,1,1,
1,1,1,1,1,1,1,1,1,1,
0,1,0,1,1,1,0,1,1,1};
int main(){
string str[100];
int point=0;
while (1){
int a[10];
int p=0;
cin>>a[0];
(二)输入10个数,第一个数单独输入以便判断录入结束。
if (a[0]==-1) break;
for (int j=1;j<10;j++) cin>>a[j];
for (int i=0;i<9;i++){
(三)对输入的数字组合进行改造,变成原数组的坐标。比对数组里面的元素是1还是0。
if (st[a[i]][a[i+1]]==1) {
p++;
}
}
(四)比对结果存入字符串数组
if (p==9) str[point]="YES";
else str[point]="NO";
point++;
}
for (int k=0;k<point;k++) cout<<str[k]<<endl;
return 0;
}
五、调试与测试
每次比较前后两个数字的时候对应的坐标应该是那两个数各自都减1(数组下标是从0开始的)这样处理不妨在录入数组的时候就寄予相应的计算。最后还要注意循环的数量。是从第一个循环到倒数第二个。这样子处理才会方便。
六、分析与总结
这道题体现了转换思维的重要性。如果没有联系到离散当中的关系矩阵就要进行很多种情况额条件假设,而这些假设将会大大增加代码的冗杂度,同时也大大降低了效率。于是这类有限结果,有限条件的题目,我们可以在main函数外面进行全部的条件假设,没举出所有的情况,这样就可以更好更快的解题了。