Codeforces 2019最後一場div2的解題報告&年終總結

2020.1.8 星期三
寒假回來了,該上學了.
寒假終於打了第一場div2,之前都是天天喊着要打,然後天天恰好錯睡 過,補題,然而終於有機會來一場真的了。這次差點又記錯時間,多虧了羅切斯特的老哥提醒,讓27號晚上九點還在跑步的我突然意識到還有一個小時比賽就開始了,不然又2019年真的就unrated了。

好吧,事實上還真的挺失敗的,只寫了第一道題,第一道題是一道簡單的php,這裏不說了,剛開始忘把freopen去掉還wa了一發。

然後第二題就比較舒(cao)服(dan)了,羣裏一部分人都幾乎是秒過了B,我原來以爲我自己可能是個好的翻譯,結果後來發現我連翻譯都做不好,回去默默地把託福110+的成績扔進垃圾桶。剛開始我以爲是要求不限個數刪除,刪掉幾個才能聽完整的,那我想就是簡單貪心嘛,樣例也過了,就提交了

WA x 1

WA的猝不及防使我感到事情有些蹊蹺,再一讀題發現原來是讓我們求能夠聽的最多的個數,但是題意總感覺有些前後矛盾,但是顧不得那麼多了,重新寫了代碼之後,用了前綴和和優先隊列之後搞了下過了樣例,交了上去

WA x 2

我哭遼這什麼情況,我和一位國內的同學幾乎是抱着哭,這道題看上去是水題,然而我真的沒想到會栽倒在這個上面,然後我研究了下我的算法,發現複雜度和算法應該都沒問題,如果有問題,那隻能說明是我的理解出錯了。

仔細讀題,發現是讓求刪掉一個下標上的數字使聖誕老人聽到的頌詞是最多的,原來是下標,哭了哭了。另外說一下,我發現這個問題已經是1小時40分鐘的時候了,久未熬夜的我腦子着實已經不太清楚了,用lis和前綴和搞了下之後發現可以過樣例了,繼續提交

WA x 3

此時比賽已經接近尾聲,只能抱憾而終了。

C題我看了,當時覺得可能是疊落方塊那樣用並查集的樣子,不過後來發現其實只是簡單模擬,並不複雜,餓,賽後補題,B我用答案的方法試了試,在第五個點TLE了,也在意料之內,畢竟python和c++還是有區別的,這裏借用一下@Mr.Skirt老哥的方法,他的方法是比較合理的,維護一個堆然後依次把所有元素推進去,然後用前綴和判斷是否可以成爲刪掉的節點,因爲在隊列中一個大的的存在勢必會增加在這點間斷的可能性,所以這樣做簡化了代碼。我也是後來想了好久才明白,其實用前綴和也應該是可以,不過我當時想的是求第一個開始的降序子序列然後和原數組進行比較,沒意識到這樣做很容易就出毛病了。代碼如下:

#include <bits/stdc++.h>
using namespace std;
#define limit 100000 + 5//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3ff
#define lowbit(i) i&(-i)//一步兩步
#define EPS 1e-6
#define ff(a) printf("%d\n",a );
#define MOD 1e9 + 7
typedef long long ll;
void read(int &x){
    char ch = getchar();x = 0;
    for (; ch < '0' || ch > '9'; ch = getchar());
    for (; ch >='0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
}//快讀
int read(){
    int x;
    char ch = getchar();x = 0;
    for (; ch < '0' || ch > '9'; ch = getchar());
    for (; ch >='0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
    return x;
}//快讀
int kase;
ll n , m;
ll a[limit],sum[limit];
int main(){
    //freopen("C:\\Users\\administrator01\\CLionProjects\\untitled14\\data.txt", "rt", stdin);
    scanf("%d", &kase);
    while(kase--){
        scanf("%lld%lld" , &n, &m);
        sum[0] = 0;
        for(int i = 1 ; i <= n ; ++i){
            scanf("%lld", &a[i]);
            sum[i] = sum[i - 1] + a[i];//前綴和
        }
        if(sum[n] <= m){
            puts("0");
            continue;
        }
        priority_queue<pair<ll,int>>q;
        int ans = 0;
        for(int i = 1 ; i <= n ; ++i){
            q.push({a[i], i});
            if(sum[i - 1] <= m){
                ans = i;
            }
            if(sum[i]  <= m + q.top().first){//等於全加起來
                ans = q.top().second;
            }
        }
        ff(ans)
    }
    return 0;
}

這個代碼是Mr.Skirt老哥的,我放在這裏只是爲了當個倉庫,如果有不妥的地方我會把它刪掉。

C題,嗯,並不是並查集,只是簡單的構造,不過得開ull,不禁讓人想到了今年csp的D1 hhhhh

剛開始寫掛了,去看tutorial,我發現我的代碼和答案驚人的相似,當時覺得沒毛病爲什麼掛我,不過後來cf提示說int爆了,然後換用ull一發入魂,ok就這麼多了。
代碼

#include <bits/stdc++.h>
using namespace std;
#define limit 100000 + 5//防止溢出
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3ff
#define lowbit(i) i&(-i)//一步兩步
#define EPS 1e-6
#define ff(a) printf("%d\n",a );
#define MOD 1e9 + 7
typedef unsigned long long ll;
void read(int &x){
    char ch = getchar();x = 0;
    for (; ch < '0' || ch > '9'; ch = getchar());
    for (; ch >='0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
}//快讀
int read(){
    int x;
    char ch = getchar();x = 0;
    for (; ch < '0' || ch > '9'; ch = getchar());
    for (; ch >='0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
    return x;
}//快讀
int kase;
ll n , m;
ll gift[limit] , seq[limit];
ll cost(ll k){
    return 2 * k + 1;
}
int pos[limit];//映射
int main(){
    //freopen("C:\\Users\\administrator01\\CLionProjects\\untitled14\\data.txt", "rt", stdin);
    kase = read();
    while(kase--){
        scanf("%lld%lld" , &n, &m);
        for(int i = 1 ; i <= n ; ++i){
            scanf("%lld", &gift[i]);
            pos[gift[i]] = i;//反向映射
        }
        for(int i = 1 ; i <= m ; ++i){
            scanf("%lld" , &seq[i]);
        }
        int fpos = -1;//第一個的位置,初始化爲無窮小
        ll ans = m;//答案//原本需要的,一個一個拿出來的,現在不需要要
        for(int i = 1 ; i <= m ; ++i){
            if(pos[seq[i]] > fpos){
                ans += 2 * (pos[seq[i]] - i);//1需要把東西送出去,花疫苗
                fpos = pos[seq[i]];
            }
        }
        printf("%lld\n", ans);
        //首先先找到第一個的位置然後再找後面的
 
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章