7.5.實驗 解題參考

Problem-A(HDU1157)
排序水題,將輸入數據排序用一次sort,輸出中位數即直接輸入第n/2個位置上的數。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[10010];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<n;i++)
             scanf("%d",&a[i]);
        sort(a,a+n);
        printf("%d\n",a[n/2]);
    }
    return 0;
}

Problem-B(HDU1106)
這一題排序的部分很簡單,將原串預處理分開,並逐一轉換成數字,對這些數字sort一遍就可以輸出了。
但是原串的預處理分割有點麻煩,需要考慮完備5出現的情況。
這裏給出幾組測試樣例,這些都過了基本就考慮完全了:
555556 //開頭有5的
1555556 //中間有一堆5的
125 //5結尾的
55552345891 //不是5結尾的
1234 //沒有5的
12345531232 //不是5結尾的
每次遍歷原串的每個位置,根據是否是5、出現5時位置與周邊的情況決定分割。具體處理見標程。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
char s[10010];
int a[10010];

int change(string s)//將字符串轉換成數字
{
    int len = s.length();
    int sum = 0;
    for(int i = len - 1, j = 0; i >= 0; --i, ++j)
        sum += (int)(s[i] - '0') * pow(10.0, j);
    return sum;
}

int main()
{
    int len, num;
    string ans;
    while(scanf("%s", s) != EOF)
    {
        len = strlen(s);
        num = 0;
        ans = "";
        for(int i = 0; i < len; ++i)
        {
            if(s[i] != '5')
            {
                ans += s[i];
                if(i == len - 1) //不是5結尾的
                    a[num++] = change(ans);
            }
            else if(s[i] == '5' && s[i - 1] != '5' && i != 0) //是5且不能一堆5且5不能爲第一個
            {
                a[num++] = change(ans);
                ans = "";
            }
        }
        sort(a, a + num);
        for(int i = 0; i < num - 1; ++i)
            printf("%d ", a[i]);
        printf("%d\n", a[num - 1]);
    }
    return 0;
}

Problem-C(HDU1031)
這一題需要做兩趟排序,第一趟是對計算出的總滿意度降序,排過之後可以確定能取到的前k項,但輸出要求按編號降序,所有對前k個元素又要按條件再排序一次。
注意爲排序方便,每個元素應該構造一個結構體,記錄其總滿意度和其編號。第一次排序對所有元素,所以範圍是【a,a+m】,第二次是取前k個,所有範圍是【a,a+k】。兩次排序條件不一樣,必須要自己寫出兩個比較函數(cmp1、cmp2)。

#include<iostream>
#include<algorithm>
using namespace std;
struct stu
{
    double m;
    int k;
};
int cmp1(stu a,stu b)
{
    if(a.m!=b.m)
    return a.m>b.m;
    else
    return a.k<b.k;
}
int cmp2(stu a,stu b)
{
    return a.k>b.k;
}
int main()
{
    int n,m,k;
    double b;
    int i;
    stu s[10000];
    while(cin>>n>>m>>k)
    {
        for(i=0;i<10000;i++) s[i].m=0;
        while(n--)
        {
            for(i=0;i<m;i++)
            {
                cin>>b;
                s[i].m+=b;
                s[i].k=i;
            }
        }
        sort(s,s+m,cmp1);
        sort(s,s+k,cmp2);
        for(i=0;i<k;i++)
        {
            cout<<s[i].k+1;
            if(i<k-1)
            cout<<' ';
        }
        cout<<endl;
    }
    return 0;
}

Problem-D
這道題有必要說一下題目大意了,稍有不慎就繞暈了TAT
題目大意:給你n個0~200之間的數,每個數對應有一個函數值,若所有的函數值出現的頻率都相等而自變量不相等時是Bad,否則輸出頻率最高的函數值,若有多個升序輸出。
前期處理很好做,就是輸入一個數,將其轉換爲函數值存起來。
然後排序就好,但排完後是要看頻率最高而不是當前數字大小。
那麼可以對排好的順序數組加個標籤,相同的數排在一起正好可以累計計數,即每組相同的數最後一個的標記數出了其出現的總個數。
有了這個計數,找頻率最高也就是找計數最大,引進一個變量m更新就好。
但可能有Bad的情況,那麼再引進一個變量sm數出關聯最大頻率(一會可能要輸出)的數的個數。如果最後它等於n,那麼小心了,這說明所有函數值出現頻率相等,肯是Bad。
爲什麼以上情況不能直接確定Bad呢(這也是我WA到落淚的地方),注意題意,頻率都相同但數值有不相同才Bad,否則照常輸出的。
所有可以通過剛剛的標記數組,看最後一個計數標記,若累計爲n說明數字全一樣,照常輸出,多累計不爲n才說明數值有不同的,所以符合(sm==n && num[n-1]!=n)的纔是Bad情況。
出去Bad的情況,直接輸出就很好輸出了,從頭到尾找一遍,如果標記計數等於最大值m,就是要輸出的元素,爲了調整換行格式,需要提前倒着找到最後一個,這是常見的輸出小技巧。
具體見程序。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[1000000],num[1000000];
int main()
{
    int T,t,n,m,sm,x;
    scanf("%d",&T);t=0;
    while(T--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&x);
            a[i]=10000-(100-x)*(100-x);
        }
        sort(a,a+n);
        for(int i=0;i<n;i++) num[i]=1;
        for(int i=1;i<n;i++)
            if(a[i]==a[i-1]) num[i]=num[i-1]+1;
        m=0;sm=0;
        for(int i=0;i<n;i++)
            if(num[i]>m){m=num[i];sm=num[i];}
            else if(num[i]==m) sm+=num[i];
        t++;printf("Case #%d:\n",t);
        if(sm==n && num[n-1]!=n) printf("Bad Mushroom\n");
        else
        {
            int j=n-1;
            while(num[j]!=m) j--;
            for(int i=0;i<j;i++)
                if(num[i]==m) printf("%d ",a[i]);
            printf("%d\n",a[j]);
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章