zoukankan      html  css  js  c++  java
  • 输入1~8,每个数字不重复

    昨天我的小伙伴可能太无聊了,然后给我一道题:输入1~8,每个数字不重复,问正确结果是什么?

    这道题不难,把纵横计算式写出来(一共6个),1~8全排列摆放在上面的8个空位上,有几个解就是几种答案,没有解说明此题有误。

    我们可以构建这个函数为:

     1 int func(int a[])
     2 {
     3     int b=0;//是否有误
     4     if(!b && a[2]%a[5] != 0)b=1;
     5 
     6     if(!b && a[0]+a[1]-9 != 4)b=1;
     7     if(!b && a[2]-a[3]*a[4] != 4)b=1;
     8     if(!b && a[5]+a[6]-a[7] != 4)b=1;
     9     if(!b && a[0]+a[2]/a[5] != 4)b=1;
    10     if(!b && a[1]-a[3]*a[6] != 4)b=1;
    11     if(!b && 9-a[4]-a[7] != 4)b=1;
    12     return b;
    13 }

    如果a[] 数组中的数不能满足如图所示的运算公式,将返回1,能满足将返回0

    下面就是如何获取1~8的全排序了,这个方法有很多,以下方法是书中常见的全排序方法。

     1 void swap(int *a, int *b)
     2 {
     3     int m;
     4     m = *a;
     5     *a = *b;
     6     *b = m;
     7 }
     8 void perm(int list[], int k, int m)
     9 {
    10     int i;
    11     if(k > m)
    12     {
    13         for(i = 0; i <= m; i++)
    14            printf("%d ", list[i]);
    15         printf("
    ");
    16     }
    17     else
    18     {
    19         for(i = k; i <= m; i++)
    20         {
    21             swap(&list[k], &list[i]);
    22             perm(list, k + 1, m);
    23             swap(&list[k], &list[i]);
    24         }
    25     }
    26 }
    27 
    28 int main()
    29 {
    30     int list[] = {1, 2, 3, 4, 5, 6, 7, 8};
    31     perm(list, 0, 7);
    32     return 0;
    33 }

    当然个人感觉最经典的还是Erlang语言的排序算法最精妙,只有这么一点:

    1 -module(lib_misc).  
    2 -export([perms/1]).  
    3 perms([])   ->  [[]];  
    4 perms(L)    ->  [ [H|T] || H <- L , T <- perms( L--[H] ) ].  

    全排序算法和判断表达式都有了,那么就把它们结合起来吧。只需要修改void perm(int list[], int k, int m)函数中的一部分代码,即可打到我们要求。

     1 void perm(int list[], int k, int m)
     2 {
     3     int i;
     4     if(k > m)
     5     {
     6         if (!func(list))
     7         {
     8             for(i = 0; i <= m; i++)
     9                 printf("%d ", list[i]);
    10             printf("
    ");
    11         }
    12     }
    13     else
    14     {
    15         for(i = k; i <= m; i++)
    16         {
    17             swap(&list[k], &list[i]);
    18             perm(list, k + 1, m);
    19             swap(&list[k], &list[i]);
    20         }
    21     }
    22 }

    8、9、10三行外面包裹了一个if判断,就达到我们所要的目的了。

    完整代码如下:

     1 #include<stdio.h>
     2 int func(int a[])
     3 {
     4     int b=0;//是否有误
     5     if(!b&&a[2]%a[5]!=0)b=1;
     6 
     7     if(!b&&a[0]+a[1]-9!=4)b=1;
     8     if(!b&&a[2]-a[3]*a[4]!=4)b=1;
     9     if(!b&&a[5]+a[6]-a[7]!=4)b=1;
    10     if(!b&&a[0]+a[2]/a[5]!=4)b=1;
    11     if(!b&&a[1]-a[3]*a[6]!=4)b=1;
    12     if(!b&&9-a[4]-a[7]!=4)b=1;
    13     return b;
    14 }
    15 
    16 int func2(int a[])
    17 {
    18     int b=0;//是否有误
    19     if(!b&&(a[0]+a[2])%a[5]!=0)b=1;
    20 
    21     if(!b&&a[0]+a[1]-9!=4)b=1;
    22     if(!b&&(a[2]-a[3])*a[4]!=4)b=1;
    23     if(!b&&a[5]+a[6]-a[7]!=4)b=1;
    24     if(!b&&(a[0]+a[2])/a[5]!=4)b=1;
    25     if(!b&&(a[1]-a[3])*a[6]!=4)b=1;
    26     if(!b&&9-a[4]-a[7]!=4)b=1;
    27     return b;
    28 }
    29 
    30 void swap(int *a, int *b)
    31 {
    32     int m;
    33     m = *a;
    34     *a = *b;
    35     *b = m;
    36 }
    37 void perm(int list[], int k, int m)
    38 {
    39     int i;
    40     if(k > m)
    41     {
    42         if (!func2(list))
    43         {
    44             for(i = 0; i <= m; i++)
    45                 printf("%d ", list[i]);
    46             printf("
    ");
    47         }
    48     }
    49     else
    50     {
    51         for(i = k; i <= m; i++)
    52         {
    53             swap(&list[k], &list[i]);
    54             perm(list, k + 1, m);
    55             swap(&list[k], &list[i]);
    56         }
    57     }
    58 }
    59 
    60 int main()
    61 {
    62     int list[] = {1, 2, 3, 4, 5, 6, 7, 8};
    63     perm(list, 0, 7);
    64     return 0;
    65 }
    全部源代码

    运行后,发现没有给出任何一组结果,我问了一下小伙伴题是不是出错了啊,小伙伴说木有。然后就想到是不是和运算符的优先级有关系呢? 假设:

     加减乘除运算只遵循从左向右,从上至下,没有优先级。 于是根据func函数变化出func2函数,替换if判断表达式中的函数,运行,yes,出结果了,也就是假设正确。

    告诉小伙伴答案后,小伙伴说正确了。

    我们会心一笑。

  • 相关阅读:
    我们在期待什么?
    ASP.NET的本质–IIS以及进程模式
    javascript开发中要注意的事情
    通过配置web.config发电子邮件详解
    VS2005 中文版下载
    td自动换行CSS
    巧妙利用图片IMG的onerror事件
    网页 页面不缓存
    JS检测对像(支持多版本)
    利用js预缓存图片
  • 原文地址:https://www.cnblogs.com/preacher/p/4742078.html
Copyright © 2011-2022 走看看