《算法设计与分析》实验报告(一)之模糊数字、真假银币

二、实验内容

1模糊数字

问题描述:一张单据上有一个5位数的编码,因为保管不善,其百位数已经变得模糊不清。但是知道这个5位数是57和67的倍数。现在要设计一个算法,输出所有满足这些条件的5位数,并统计这样的数的个数。

输入:每一行对应一个测试样例,每一行包含4个数字,依次是万位数、千位数、十位数和个位数。最后一行包含四个-1,表示输入结束。

输出:每组测试样例的结果输出占一行,第一个数字表示满足条件的编码个数,后面按升序输出所有满足条件的编码,数字与数字之间用空格隔开。

2 真假银币

问题描述:张三有12枚银币,其中有11枚真币和1枚假币。假币看起来和真币完全一样,但是它们的重量不一样。很遗憾的是,张三不知道假币比真币轻还是重。但他办公室有一架天平,还有一个聪明的助手。经过精心安排每次的称重,助手保证在称3次后确定发现假币。助手想跟张三开一个玩笑,只告诉他每次称重的方案和天平的状态,但是不告诉他哪个是假币,假币比真币轻还是重。请设计一个算法帮助张三辨别真假银币。

输入:第一行包含一个正整数,表示测试数据的组数。每组测试数据有三行,每行表示一次称重的结果。张三和助手事先把银币标号为A~L。每次称重的结果用3个以空格隔开的字符串表示:天平左边放置的银币标号,天平右边放置的银币标号,以及平衡状态。其中平衡状态分别用up、down和even表示,分别表示右端高、右端低和平衡。另外,每次称重天平左右的银币数总是相等的。

输出:每组测试数据的输出占一行,输出假银币的标号,并指明它比真银币轻还是重,轻则输出light,重则输出heavy。

程序代码:

1模糊数字

#include <string.h>

#include <stdio.h>

int main()

{

   int d1,d2,d4,d5, x, iValue;

   int y = 0, i = 0, j = 0, k = 0;

   int geshu[5], iResult[10];

   do

   {

       scanf("%d%d%d%d", &d5, &d4, &d2, &d1);

       if (d5 != -1) {

           for (x = 0; x <= 9; x++)

          {

              iValue = d5 * 10000 + d4 * 1000 + x * 100 + d2 * 10 + d1;

              if ((iValue % 57 == 0) && (iValue % 67 == 0))

              {

                 y = y + 1;

                 iResult[j] = iValue;

                 j++;

              }

          }

          geshu[i] = y;

          i++;

          k++;

       }

   } while (d5 != -1);

   j = 0;

   for (i = 0; i <= k; i++)

   {

       for (j; j < geshu[i]; j++)

          printf("%d %d\n", geshu[i], iResult[j]);

   }

   return 0;

}

2真假银币

#include <stdio.h>

#include <string.h>

#define N  3

#define M 8

char left2[N][M], right2[N][M], result[N][M];



int judge(char c, int heavy)

{

    int i;

    for (i = 0; i < N; i++) {

        if (result[i][0] == 'e') {

            if (strchr(left2[i], c) != NULL || strchr(right2[i], c) != NULL)

                return 0;

        }

        else if (result[i][0] == 'u') {

            if (heavy) {

                if (strchr(left2[i], c) == NULL)

                    return 0;

            }

            else {

                if (strchr(right2[i], c) == NULL)

                    return 0;

            }

        }

        else if (result[i][0] == 'd') {

            if (heavy) {

                if (strchr(right2[i], c) == NULL)

                    return 0;

            }

            else {

                if (strchr(left2[i], c) == NULL)

                    return 0;

            }

        }

    }

    return 1;

}



int main()

{

    int n, i;

    char c;

    scanf("%d", &n);

    while (n--) {

        for (i = 0; i < N; i++)

            scanf("%s%s%s", left2[i], right2[i], result[i]);



        for (c = 'A'; c <= 'L'; c++) {

            if (judge(c, 1)) {

                printf("%c is the counterfeit coin and it is heavy.\n", c);//判断结果为重

                break;

            }

            if (judge(c, 0)) {

                printf("%c is the counterfeit coin and it is light.\n", c);//判断结果为轻

                break;

            }

        }

    }



    return 0; }

程序测试及运行结果:

1模糊数字

2 真假银币

分析与讨论:

1、 要用掌握一种算法,首先要理解它的思想,就这次实验而言,要理解分治的算法思想,分治要用递归来实现。清楚算法思想后问题就迎刃而解了。还有就是多练习用分治来解决一些实际问题对于更好地掌握分治是有很大帮助的。要掌握它,我还要多练习写这方面的程序。

2、 递归算法是一种通过重复将问题分解为同类的子问题而解决的方法。该算法的思想是很简便,但是计算量很大,计算的效率很低,利用相同类似的迭代和尾递推的算法,效率大大地提高了。而分治算法则是将一个规模为N的问题分解为K个子问题,这些子问题相互独立而且原问题性质相同。求出问题的解,就可以得到原问题的解了。我觉得简单来说就是分目标解决程序问题的一种算法。对硬币问题来说,就是利用其相关的原理,把大的的硬币集合一一分解成小的硬币集合一次次去分解,直到棋盘分解为最小则结束。

  • 25
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

了一li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值