計算機學院2013級的院草語文難同學是軟院院花牟黑黑愛慕的對象,因此牟黑黑經常約楠神去逛街,楠神不喜歡陪牟黑黑逛街,但是不得不從啊。所以在牟黑黑逛街的時候他就無聊的用眼睛識別條形碼 。
在生活中,條形碼經常用來標誌物品的信息。條形碼是由黑白相間的條組成的。條的寬度有兩種,我們可以認爲窄的代表0,寬的代表1。本題中設定寬條的寬度是窄條的兩倍。
楠神擁有很強的DIY精神,他決定做一個條形碼識別工具。首先他完成了圖像識別部分,得到了一系列條的寬度。他希望將這些寬度識別爲一個01串。本來這是一個非常簡單的任務,可是由於楠神在識別的時候會有誤差,使得問題變得沒那麼簡單了。不過楠神認爲測量得到的結果最多比真實值大或小5%。請你幫忙完成這個識別程序。已知條形碼中至少有一個是寬條,可能沒有窄條。
輸入第一行爲一個數字n(n<20),表示楠神識別出了n個條。
第二行爲n個正整數,均不大於10^8。
輸出爲一個長度爲n的01串,寬條對應1,窄條對應0。如果有些條偏差的超過了限制,輸出“Bad Barcodes”
數據範圍不大,思路也不難,但是用例很坑,卡那些莫名其妙的錯誤。就我知道的而言,好多人都是隻錯一個用例,而且每個人錯的用例編號還都不一樣。
一開始我的思路是找最大的數,然後找到寬條的平均值的最大最小範圍,由此找窄條的平均值,再看這些條是否合適就行了。但是這個思路有個問題,因爲平均值可以是小數,而找到最大最小範圍之後我最多就是用循環,讓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;
}