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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章