1. 程式人生 > >5月9日貪心考試總結

5月9日貪心考試總結

至少 -- 加工 需要 順序 const 心態 打了 而是

5月9日貪心考試總結

自制考試鏈接:https://www.luogu.org/contestnew/show/16837

這次考試沒有經過任何復習,我就想知道考出來是啥樣子。


遊記部分


考前inf小時:

我:“你是復習貪心還是背地生?”

GSC大佬:“當然是復習貪心了啊!”說罷,拿出了生物書。

JMR大佬:“肯定是背地生了啊!我明天肯定會爆(A)零(K)。”

文化課大佬QHY:“JMR你肯定爆(A)零(K)”

CXY大佬:“那你呢?”說罷,拿出了生物書。

果然是神仙啊%%%。

考前0.1小時:

我:“這次絕對不會考加工生產調度問題。”

YYQ大佬:“???”

我:“這次肯定要考種樹(區間選點)。”

YYQ大佬:“???”

我:“這次可能要考噴水裝置。”

YYQ大佬:“???”

果然是神仙啊%%%。

考試時:

經過我某條以腳趾為神經中樞的反射弧做出的反應,我要按順序開題。

看到T1(diet):我的天哪!不是說好考貪心的嗎???這是 ······ 什麽毒瘤東西???

境澤曰:“甚香!”

於是我去看了T2(fruit)。這不是我做過的原題嗎?使用STL幾分鐘切掉

然後我又回去看了T1。

境澤曰:“甚香!”

這不是道紅題嗎?真是尷尬。兩分鐘切了。

於是我去看了T3。

這是 ······ 噴水???完了。然後就去看了T4。

woc不是說好貪心的嗎???這是 ······ 註明了的暴搜???這題我之前好像是打表過的啊?

於是我就打了個暴搜。

數據範圍:n≤200,2≤k≤6。

於是我輸入了200 6

2.7e-4 小時過去了......

沒有輸出!!!

心態崩了,要爆零了!!!

這時,CXY說過的一句話在我腦海中閃現——

"記搜不就是有技巧的搜索嗎?"

於是我剪了個枝,好像沒有超時。於是我又去剛T3(仿佛不叫剛)

"這次肯定要考種樹(區間選點)"。

還真考到了。這不就是個種雷達嗎?於是我就切了它。

這時,GSC大佬:“我覺得T3比T4難。”

%%%果然是大佬

剩下半小時,沒有查錯,沒有對拍,而是——

和YYQ大佬頹太空彈珠???

考後:

於是 ...... 我就這樣AK了。


題解部分


T1:

這是道簽到題(至少寫完後的我是這麽認為的)。只需要把所有食物按脂肪從大到小排序,取最多脂肪的食物,然後把當前種類的可選個數的限制減一,當然,如果可選的個數為0,那就直接continue;。這樣就可以獲得最優解了。證明略。第一題真沒什麽好說的。

代碼:

#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
#include<cstring>
using namespace std;

const int MaxN=505;
int n,m,k;
int num[MaxN];
struct food {
    int col,fat;
}a[MaxN];

void init()
{
    freopen("diet.in","r",stdin);
    freopen("diet.out","w",stdout);
}

bool cmp(food a,food b)
{
    return a.fat>b.fat;
}

int main()
{
    init();
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=k;i++) scanf("%d",&num[i]);
    for(int i=1;i<=n;i++) scanf("%d%d",&a[i].fat,&a[i].col);
    sort(a+1,a+1+n,cmp);
    int cnt=0,ans=0;
    for(register int i=1;i<=n;i++) {
        int col=a[i].col,fat=a[i].fat;
        if(num[col]>0) {
            ans+=fat;
            num[col]--;
            cnt++;
        }
        if(cnt==m) break;
    }
    printf("%d",ans);
}

T2:

要求用優先隊列,那我們就用。這道題的策略肯定是每次選出最小的兩堆果子,合並後再排序。當然快排很浪費,是會超時的。我們使用小根堆來實現。這種水題也沒什麽好說的。

我的代碼:

#include<iostream>
#include<cstdio>
#include<queue>
#include<fstream>
using namespace std;

priority_queue<int,vector<int>,greater<int> >q;
int n;

inline void init()
{
    freopen("fruit.in","r",stdin);
    freopen("fruit.out","w",stdout);
}

int main()
{
    init();
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        int x;
        scanf("%d",&x);
        q.push(x);
    }
    int ans=0;
    while(q.size()>1) {
        int x=q.top();q.pop();
        int y=q.top();q.pop();
        ans+=x+y;
        q.push(x+y);
    }
    printf("%d",ans);
}

T3:

這題引入了平面直角坐標系,看起來比較復雜,但實際上就是板子。我們先預處理出每個島可被觀察的區間,也就是說每個區間內要求有一個雷達。這就是區間選點的板子了。板子就沒什麽好說的了。

#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;

const int MaxN=1005;
struct segment {
    double l,r;
}a[MaxN];
int n;
double d;
int num[MaxN];

inline double calc(double y)
{
    return sqrt(d*d-y*y);
}

inline void init()
{
    scanf("%d%lf",&n,&d);
    for(register int i=1;i<=n;i++) {
        double x,y;
        scanf("%lf%lf",&x,&y);
        if(y>d) {
            printf("-1");
            exit(0);
        }
        double len=calc(y);
        a[i].l=x-len;
        a[i].r=x+len;
        num[i]=1;
    }
}

bool cmp(segment x,segment y)
{
    return x.r<y.r;
}

inline void work()
{
    int ans=0;
    sort(a+1,a+1+n,cmp);
    int now=0;
    for(int i=1;i<=n;i++) {
        double nowr=a[i].r;
        if(num[i]<=0) continue;
        num[i]--;
        for(register int j=i+1;j<=n;j++) {
            if(a[j].l<=nowr) {
                num[j]--;
            }
        }
        ans++;
    }
    printf("%d",ans);
}

int main()
{
    init();
    work();
}

T4:

這道是老師故意出的超綱題。肯定不帶腦子暴搜是會 T 掉的(如果傻到一種境界還會WA)。首先需要判重。在暴搜剪枝中,記last是一種常見的策略。所以我們就記一個last,每次下一個數必定大於last,這樣我們搜出的組合就是單調不降的,就不會重了。然後考慮T的問題。我們發現,當下一個數過大時,就沒有保持序列單調不降的可能了。所以我們再加一個可行性剪枝,枚舉量就會大大減少了。

代碼:

#include<iostream>
#include<cstdio>
#include<fstream>
using namespace std;

int n,k;
int ans=0;
int sum=0;

inline void init()
{
    freopen("divide.in","r",stdin);
    freopen("divide.out","w",stdout);
}

inline void dfs(int l,int a)
{
    sum++;
    if(sum==k+1) {
        if(a==0)
        ans++;
    }
    else {
        for(register int i=l;i<=a-i*(k-sum);i++) {
            dfs(i,a-i);
        }
    }
    sum--;
}

int main()
{
    init();
    scanf("%d%d",&n,&k);
    dfs(1,n);
    printf("%d",ans);
}

總結部分


雖然這次AK了,但仍有很多不足:

1、眼瞎。看錯了多少題意?紅題都能看成毒瘤?幸好我心態不差,不然就爆零了。

2、頹廢。寫完就頹,萬一文件錯了怎麽辦?幸好臉好,不然就爆零了。

3、急躁。寫題的時候手忙腳亂的。這樣容易寫炸。幸好我臉好,沒有炸。

1: 焦鳴睿還真爆零了
2: YYQ怎麽回事?我不是說了要考種樹嗎?
3: GSC和CXY把T3弄成了大模擬海星

5月9日貪心考試總結