我的涨分日记(二)——BestCoder Round #59

来源:互联网 发布:淘宝上的男装店铺 编辑:程序博客网 时间:2024/05/15 04:57

哎呀,好久没有更新博客啦,今天又刷了一波BC,而且又涨分,还是蛮开心的。

近来很多人告知了我的不足,我也渐渐体会到自己小题做的越来越好了,但是大题还是没有思路。

肯定是我光刷小题,不去学算法,大题也做的不多,结果才会这样。

虽说学算法是个日积月累的过程,但我看我要抓紧步伐,开始一些比较难一点的算法的学习了。



HDU-5499  SDOI

看不懂英文的同学去Bestcoder里面看中文版把(我估计英文版做出来是够呛的)

思路:这道题目不是特别难,但是特别烦,假设这不是一道中文题,让我用英文来看的话,我不知道自己还能不能很快做出来,甚至能不能做出来。我的话比较习惯用结构体排序。先读取数据,将两次最高的分数保存,如果遇到女性用flag记录。然后再计算一遍每个人的最终分数,排序!最后就是将最佳女选手挑出,如果flag记录了,那么就从前往后查找第一个女性选手。如果她在前m个,那么就不用移动;但是如果她不在前m个,那么就将她与第m个选手交换位置。输出答案!

#include <map>#include <set>#include <stack>#include <cmath>#include <queue>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstdlib>#include <sstream>#include <cstring>#include <iostream>#include <algorithm>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define clr(x,y) memset(x,y,sizeof(x))#define maxn 100+5#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef long long ll;struct man{    char name[25];    int sex,r1,r2;    double r;    friend bool operator < (const man& A,const man& B)    {        return A.r > B.r;    }}a[maxn];int main(){    int t,n,m;    scanf("%d",&t);    while(t--)    {        int flag=0,ma1=0,ma2=0;        scanf("%d %d",&n,&m);        for(int i=0;i<n;i++)        {            char k[10];            scanf("%s %s %d %d",a[i].name,k,&a[i].r1,&a[i].r2);            ma1=max(ma1,a[i].r1);            ma2=max(ma2,a[i].r2);            if(k[0]=='m')a[i].sex=1;            else a[i].sex=0,flag=1;        }        for(int i=0;i<n;i++)            a[i].r=(1.0*a[i].r1/ma1)*300*0.3+(1.0*a[i].r2/ma2)*300*0.7;        sort(a,a+n);        if(flag)        {            for(int i=0;i<n;i++)            {                if(!a[i].sex)                {                    if(i+1>m)                    {                        swap(a[i],a[m-1]);                    }                    break;                }            }        }        puts("The member list of Shandong team is as follows:");        for(int i=0;i<m;i++)            printf("%s\n",a[i].name);    }    return 0;}


HDU- 5500  Reorder the Books

中文题意自己去搜吧~哈哈哈~~~
思路:比赛的时候还是比较机智的,一下就想出来O(N)的算法了。
官方题解太复杂了0 0, 我这里比较简单的说一下。
我们简单一想会发现不管是什么样的组合我们最多取n-1次就一定能将书排好序。
然后首先考虑编号最大的那个(因为编号最大的那个要放在最下面,我喜欢从下面来),判定最大编号的位置,那么最大编号下面的书是一定要被抽出来的(因为要把最大编号的放在最下面),那么我为什么不按照他们的编号顺序大小来抽,让他们放到上面的顺序是有序的,有这个考虑我就可以暂时不抽。然后我考虑次大编号的那本书(比最大编号小1的那本书),如果次大编号在最大编号的上面,那么次大编号的书是不用被抽走的,要抽走的只是在次大编号和最大编号之间的书,但是考虑到上面的思考我暂时不抽;如果次大编号在最大编号下面,那我现在抽走这本次大编号就是最机智的(次大编号书是早晚要抽走的,因为次大编号书不能在最大编号书的下面,如果先抽走别的书再抽走次大编号的书,两者相比较只是增加两本书之间的多余的书,反而费事了),那么这时次大编号书就是第一本了,按照刚才的理论,除了次大编号书与最大编号书之外的所有书都要被抽走,那么就相当于如果次大编号的书在最大编号书的下面,那么就不用看了,因为这时除了刚才选好的最大编号书,其他所有书都有被抽出,这样结束了。那么按照这个顺序,我的算法是从数组的尾开始往前寻找最大编号的,找到最大编号再找次大编号,以此类推,直至找到数组头,中途不回头。这时找到第几个编号,那么就至少需要操作几次。
#include <map>#include <set>#include <stack>#include <cmath>#include <queue>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstdlib>#include <sstream>#include <cstring>#include <iostream>#include <algorithm>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define clr(x,y) memset(x,y,sizeof(x))#define maxn 100+5#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef long long ll;int a[30];int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n;        scanf("%d",&n);        for(int i=1;i<=n;i++)            scanf("%d",a+i);        int k=n;        for(int i=n;i>=1;i--)            if(a[i]==k)k--;        printf("%d\n",k);    }    return 0;}


HDU-5501  The Highest Mark

这道题容我在思考一下。。。

0 0