C语言 拨钟问题的两种解法。

拨钟问题
描述
有9个时钟排成一个3*3的矩阵,从上到下从左到右依次标为ABCDEFGHI。
每个时钟只有1个时针,时针初始指向3、6、9或12点。
对每一个时钟的时针共允许有9种不同的移动,每个移动会将若干个时钟的指针沿顺时针方向拨动90度。
移动 影响的时钟
1 ABDE
2 ABC
3 BCEF
4 ADG
5 BDEFH
6 CFI
7 DEGH
8 GHI
9 EFHI

输入
多组测试数据,每组测试数据3行3列,共9个整数,表示各时钟指针的起始位置,相邻两个整数之间用单个空格隔开。其中,0=12点、1=3点、2=6点、3=9点。

输出
每组测试数据在一行中输出一个最短的移动序列,使得9个时钟的指针都指向12点。按照移动的序号从小到大输出结果。相邻两个整数之间用单个空格隔开。

样例输入
3 3 0
2 2 2
2 1 2
样例输出

4 5 8 9
我们可以分析每个时钟被影响的移动方式有哪些
例如A会被移动1,2,4影响
题目就不过多地分析了,大佬们的博客都讲得很清楚了,我自己语言能力有限,担心自己表达得不好。
A:1,2,4
B:1,2,3,5
C:2,3,6
D:1,4,5,7
E:1,3,5,7,9
F:3,5,6,9
G:4,7,8
H:5,7,8,9
I:6,8,9

方法一(暴力法):

#include<stdio.h>
#define cir(i) for(int i=0;i<4;i++)
int main()
{
    int a[10],b[10];
    int min;
    int sum;
    while(~scanf("%d",&a[0]))
    {
        min=2e9;
        for(int i=1;i<9;i++) scanf("%d",&a[i]);
        cir(i1)cir(i2)cir(i3)cir(i4)cir(i5)cir(i6)cir(i7)cir(i8)cir(i9)
        {
            if(!((i1+i2+i4+a[0])%4)&&!((i1+i2+i3+i5+a[1])%4)&&!((i2+i3+i6+a[2])%4)&&!((i1+i4+i5+i7+a[3])%4)&&!((i1+i3+i5+i7+i9+a[4])%4)&&!((i3+i5+i6+i9+a[5])%4)&&!((i4+i7+i8+a[6])%4)&&!((i5+i7+i8+i9+a[7])%4)&&!((i6+i8+i9+a[8])%4))
            {
                sum=i1+i2+i3+i4+i5+i6+i7+i8+i9;
                if(sum<min)
                {
                    min=sum;
                    b[0]=i1;
                    b[1]=i2;
                    b[2]=i3;
                    b[3]=i4;
                    b[4]=i5;
                    b[5]=i6;
                    b[6]=i7;
                    b[7]=i8;
                    b[8]=i9;
                }
            }
        }
        for(int i=0;i<9;i++)
        {
            while(b[i]--)
                printf("%d ",i+1);
        }
        printf("\n");
    }
    return 0;
}

方法二

#include<stdio.h>
#define cir(i) for(int i=0;i<4;i++)
int main()
{
    int a[10],b[10];
    int min;
    int sum;
    while(~scanf("%d",&a[0]))
    {
        min=2e9;
        for(int i=1;i<9;i++) scanf("%d",&a[i]);
        int i5,i6,i7,i8,i9;
        cir(i1)cir(i2)cir(i3)cir(i4)
        {
            if((i1+i2+i4+a[0])%4==0)//确定了A
            {
                i5=(4-(i1+i2+i3+a[1])%4)%4;//确定了B
                i6=(4-(i2+i3+a[2])%4)%4;//确定了C
                i7=(4-(i1+i4+i5+a[3])%4)%4;//确定了D
                i8=(4-(i4+i7+a[6])%4)%4;//确定了G
                i9=(4-(i1+i3+i5+i7+a[4])%4)%4;//确定了E
                //i1-i9确定完毕,下面分别验证F,H,I.
                if((i3+i5+i6+i9+a[5])%4==0&&(i5+i7+i8+i9+a[7])%4==0&&(i6+i8+i9+a[8])%4==0)
                {
                    sum=i1+i2+i3+i4+i5+i6+i7+i8+i9;
                    if(sum<min)
                    {
                        min=sum;
                        b[0]=i1;
                        b[1]=i2;
                        b[2]=i3;
                        b[3]=i4;
                        b[4]=i5;
                        b[5]=i6;
                        b[6]=i7;
                        b[7]=i8;
                        b[8]=i9;
                    }
                }
            }
        }
        for(int i=0;i<9;i++)
        {
            while(b[i]--)
                printf("%d ",i+1);
        }
        printf("\n");
    }
    return 0;
}

大一新生一枚
题目来源于学校的OJ平台
第一次做这道题有点蒙
第一种暴力法来源于学校老师的视频讲解
老师对第二种方法一带而过,本人懒不想写,
在CSDN没有找到C语言的第二种方法,那干脆就自己写吧。
两种方法都过了学校的OJ平台
可以清晰地看到方法一耗时明显多于方法二
[第一个是方法二,第二个是方法一]

第一次发文,有点小激动。
希望未来我会一直努力,有朝一日能成为IT界的大佬!
关于代码,若有不足之处,非常希望您指正出来!

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值