我的漲分日記(二)——BestCoder Round #59

哎呀,好久沒有更新博客啦,今天又刷了一波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|1
typedef 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|1
typedef 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

這道題容我在思考一下。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章