描述 有9个时钟,排成一个3*3的矩阵。现在需要用最少的移动,将9个时钟的指针都拨到12点的位置。 共允许有9种不同的移动。如下表所示,每个移动会将若干个时钟的指针沿顺时针方向拨动90度。
输入 从标准输入设备读入9个整数,表示各时钟指针的起始位置。0=12点、1=3点、2=6点、3=9点。
输出 输出一个最短的移动序列,使得9个时钟的指针都指向12点。按照移动的序号大小,输出结果。
样例输入 3 3 0 2 2 2 2 1 2
样例输出 4 5 8 9
来源 1166
分析 1、题目中的样例输入虽然是3X3的二维数组,但是此题中各元素相互关联不大,为简化代码的复杂度,可以直接使用长度为9的一维数组存储输入的时钟状态; 2、要使全部时钟状态都拨到12点位置,则数组中各元素最后的值全部都是4的倍数或者0; 3、对每一个时钟而言,把其最初的状态数字和移动的次数相加,结果能够整除4,就说明移动到12点了; 4、我们采用蛮力法,对每一个时钟,把每一个可以拨动它的方案从0次开始尝试,由于走4次就回到原位置了,所以每个时钟最多拨动3次,当9个时钟全部吻合条件时,将9种方案的次数保存下来,并输出对应的数字。
代码(C语言)
#include <stdio.h>int main(){ int time[9] = {0}; // 定义数组保存时钟初始状态 int i,i1,i2,i3,i4,i5,i6,i7,i8,i9; for(i=0;i<9;i++){ scanf("%d",&time[i]); } int min = 40; //每组最多走4次,9组最多有36次,不妨假设最多走40次,并设置为最小次数 int result[9] = {0}; for(i1=0;i1<4;i1++){ for(i2=0;i2<4;i2++){ for(i3=0;i3<4;i3++){ for(i4=0;i4<4;i4++){ for(i5=0;i5<4;i5++){ for(i6=0;i6<4;i6++){ for(i7=0;i7<4;i7++){ for(i8=0;i8<4;i8++){ for(i9=0;i9<4;i9++){ if((i1+i2+i4+time[0])%4==0 && (i1+i2+i3+i5+time[1])%4==0 && (i2+i3+i6+time[2])%4==0 && (i1+i4+i5+i7+time[3])%4==0 && (i1+i3+i5+i7+i9+time[4])%4==0 && (i3+i5+i6+i9+time[5])%4==0 && (i4+i7+i8+time[6])%4==0 && (i5+i7+i8+i9+time[7])%4==0 && (i6+i8+i9+time[8])%4==0){ int sum = i1+i2+i3+i4+i5+i6+i7+i8+i9; if(sum < min){ //将次数少的组合方案保存到result数组中 min = sum; result[0] = i1; result[1] = i2; result[2] = i3; result[3] = i4; result[4] = i5; result[5] = i6; result[6] = i7; result[7] = i8; result[8] = i9; } } } } } } } } } } } int j; for(j=0;j<9;j++){ //从0开始循环,可以将结果从小到大输出,就不需要进行额外的排序了 while(result[j] != 0){ //当result[j]为0时,就跳过循环,不输出任何内容 PRintf("%d ",j+1); result[j] --; } } return 0;}新闻热点
疑难解答