网教11.识别条形码

计算机学院2013级的院草语文难同学是软院院花牟黑黑爱慕的对象,因此牟黑黑经常约楠神去逛街,楠神不喜欢陪牟黑黑逛街,但是不得不从啊。所以在牟黑黑逛街的时候他就无聊的用眼睛识别条形码 。

在生活中,条形码经常用来标志物品的信息。条形码是由黑白相间的条组成的。条的宽度有两种,我们可以认为窄的代表0,宽的代表1。本题中设定宽条的宽度是窄条的两倍。

楠神拥有很强的DIY精神,他决定做一个条形码识别工具。首先他完成了图像识别部分,得到了一系列条的宽度。他希望将这些宽度识别为一个01串。本来这是一个非常简单的任务,可是由于楠神在识别的时候会有误差,使得问题变得没那么简单了。不过楠神认为测量得到的结果最多比真实值大或小5%。请你帮忙完成这个识别程序。已知条形码中至少有一个是宽条,可能没有窄条。

输入第一行为一个数字n(n<20),表示楠神识别出了n个条。

第二行为n个正整数,均不大于10^8。

输出为一个长度为n的01串,宽条对应1,窄条对应0。如果有些条偏差的超过了限制,输出“Bad Barcodes”

  测试输入关于“测试输入”的帮助 期待的输出关于“期待的输出”的帮助 时间限制关于“时间限制”的帮助 内存限制关于“内存限制”的帮助 额外进程关于“{$a} 个额外进程”的帮助
测试用例 1 以文本方式显示
  1. 4↵
  2. 99 105 200 199↵
以文本方式显示
  1. 0011↵
1秒 64M 0
题解:
数据范围不大,思路也不难,但是用例很坑,卡那些莫名其妙的错误。就我知道的而言,好多人都是只错一个用例,而且每个人错的用例编号还都不一样。
一开始我的思路是找最大的数,然后找到宽条的平均值的最大最小范围,由此找窄条的平均值,再看这些条是否合适就行了。但是这个思路有个问题,因为平均值可以是小数,而找到最大最小范围之后我最多就是用循环,让i从最小走到最大,i每次加1.可是这样就会错过很多数,毕竟平均值本质上是一个实型的数。我以为可以凑合凑合混过去。。可是还是被卡住了。
然后我就去寻求帮助了。得知通过先判断哪些是窄条,再让窄条乘2,这样就只用判断最大的和最小的相差是否是0.95和1.05的差距就行了。
因为有可能全是宽条,所以就先判断一下就行了。这种思想很巧妙,可以记下来。
AC代码:
#include<stdio.h>  
#include<string.h>  
#include<stdlib.h>  
double num[25], a[25];  
int vis[25];  
int n;  
int comp(const void*a, const void*b)  
{  
    return *(double*)a - *(double*)b;  
}  
  
int main()  
{  
    scanf("%d", &n);  
    int i;  
    for (i = 0; i < n; i++)  
    {  
        scanf("%lf", &a[i]);  
        num[i] = a[i];  
    }  
    qsort(num, n, sizeof(double), comp);  
    double ave = (num[0] + num[n - 1]) / 2;  
    int flag = 0;  
    if (num[0] >= ave*0.95)  
    for (i = 0; i < n; i++)  
        vis[i] = 1;//最小的一个也在大数的范围中,说明没有窄条  
    else  
    {  
        int mine = num[n - 1], maxe = num[0];  
        for (i = 0; i < n; i++)  
        if (a[i]>ave)  
        {  
            vis[i] = 1;  
            mine = mine < a[i] ? mine : a[i];  
            maxe = maxe>a[i] ? maxe : a[i];  
        }  
        else  
        {  
            vis[i] = 0;//先做标记,把大于中间值和小于中间值的两组数分开  
            a[i] = 2 * a[i];//让小的那些数翻倍,这样就不用再考虑小的数的ave了  
            mine = mine < a[i] ? mine : a[i];  
            maxe = maxe>a[i] ? maxe : a[i];  
        }  
        ave = (mine + maxe) / 2;  
        for (i = 0; i < n; i++)  
        if (a[i]>1.05*ave || a[i] < 0.95*ave)  
        {  
            printf("Bad Barcodes\n");  
            return 0;  
        }  
    }  
    for (i = 0; i < n; i++)  
        printf("%d", vis[i]);  
    printf("\n");  
    return 0;  
}  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值