1. 程式人生 > 其它 >《NEC Programming Contest 2021(AtCoder Beginner Contest 229)》

《NEC Programming Contest 2021(AtCoder Beginner Contest 229)》

A:簽到

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 5;
const int M = 1e6 + 5;
const LL Mod = 1e9 + 7;
#define INF 1e9
#define IN_INF 0x3f3f3f
#define dbg(ax) cout << "now this num is " << ax << endl;

void solve() { 
    
string s1,s2; cin >> s1 >> s2; int cnt = 0,f1 = 0,f2 = 0; for(int i = 0;i < 2;++i) { if(i == 0) { if(s1[i] == '#') { cnt++; if(s1[1] != '#' && s2[0] != '#') f1 = 1; } if(s2[i] == '#') { cnt
++; if(s2[1] != '#' && s2[0] != '#') f1 = 1; } } else { if(s1[i] == '#') { cnt++; if(s1[0] != '#' && s2[1] != '#') f1 = 1; } if(s2[i] == '#') { cnt++;
if(s2[0] != '#' && s2[1] != '#') f1 = 1; } } } if(cnt <= 1) printf("Yes\n"); else { printf("%s\n",f1 ? "No" : "Yes"); } } int main() { solve(); // system("pause"); return 0; }
View Code

B:簽到

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 5;
const int M = 1e6 + 5;
const LL Mod = 1e9 + 7;
#define INF 1e9
#define IN_INF 0x3f3f3f
#define dbg(ax) cout << "now this num is " << ax << endl;

void solve() { 
    string s1,s2;
    cin >> s1 >> s2;
    reverse(s1.begin(),s1.end());
    reverse(s2.begin(),s2.end());
    int mi = min(s1.size(),s2.size()),f = 0;
    for(int i = 0;i < mi;++i) {
        int ad = s1[i] - '0' + s2[i] - '0';
        if(ad >= 10) f = 1;
    }
    printf("%s\n",f ? "Hard" : "Easy");
}   
int main() {
    solve();
//    system("pause");
    return 0;
}
View Code

C:簽到

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 5;
const int M = 1e6 + 5;
const LL Mod = 1e9 + 7;
#define INF 1e9
#define IN_INF 0x3f3f3f
#define dbg(ax) cout << "now this num is " << ax << endl;

struct Node{int a,b;}p[M];
bool cmp(Node a,Node b) {return a.a > b.a;}
void solve() { 
    int n,w;scanf("%d %d",&n,&w);
    for(int i = 1;i <= n;++i) scanf("%d %d",&p[i].a,&p[i].b);
    sort(p + 1,p + n + 1,cmp);
    LL ans = 0;
    for(int i = 1;i <= n;++i) {
        if(w >= p[i].b) {
            ans += 1LL * p[i].b * p[i].a;
            w -= p[i].b;
        }
        else {
            ans += 1LL * w * p[i].a;
            break;
        }
    }
    printf("%lld\n",ans);
}   
int main() {
    solve();
  //  system("pause");
    return 0;
}
View Code

D:可以發現這裡左右移動都是差不多的。

所以我們可以欽定一個左端點,然後去檢查能得到的最大右端點。

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 5;
const int M = 1e6 + 5;
const LL Mod = 1e9 + 7;
#define INF 1e9
#define IN_INF 0x3f3f3f
#define dbg(ax) cout << "now this num is " << ax << endl;

vector<int> vec;
int d[N],val[N],cnt[N],mx[N];
void solve() { 
    string s;
    int k;
    cin >> s >> k;
    int n = s.size();
    // int tot1 = 0,len2 = 0;
    // for(int i = 0;i < s.size();++i) {
    //     if((i == 0 || s[i - 1] == '.') && s[i] == 'X') {
    //         if(tot1 == 0) len2 = 0;
    //         d[++tot1] = len2;
    //         val[tot1] = 1;
    //         len2 = 0;
    //     }
    //     else if(s[i] == 'X') {
    //         val[tot1]++;
    //     }
    //     else ++len2;
    // }
    for(int i = 1;i <= n;++i) {
        cnt[i] = cnt[i - 1];
        if(s[i - 1] == '.') cnt[i]++;
        mx[cnt[i]] = i;
    }
    int ans = 0;
    for(int i = 1;i <= n;++i) {
        int r = cnt[i - 1] + k;
        int ss = cnt[n] - cnt[i - 1];
        if(k >= ss) ans = max(ans,n - i + 1);
        else {
            ans = max(ans,mx[r] - i + 1);
        }
      //  dbg(ans);
    }
    printf("%d\n",ans);

}   
int main() {
    solve();
    //system("pause");
    return 0;
}
View Code

E:倒著並查集維護即可

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 5;
const int M = 1e6 + 5;
const LL Mod = 1e9 + 7;
#define INF 1e9
#define IN_INF 0x3f3f3f
#define dbg(ax) cout << "now this num is " << ax << endl;

struct Node{int L,r;}p[M];
int fa[N];
int Find(int x) {return x == fa[x] ? x : fa[x] = Find(fa[x]);}
vector<int> G[N],tmp;
void solve() { 
    int n,m;scanf("%d %d",&n,&m);
    for(int i = 1;i <= m;++i) {
        scanf("%d %d",&p[i].L,&p[i].r);
        G[min(p[i].L,p[i].r)].push_back(max(p[i].L,p[i].r));
    }
    int ans = 0;
    for(int i = 1;i <= n;++i) fa[i] = i;
    for(int i = n;i >= 1;--i) {
        tmp.push_back(ans);
        for(auto v : G[i]) {
            int x = Find(v),y = Find(i);
            if(x != y) {
                ans--;
                fa[x] = y;
            }
        }
        ans++;
    }
    reverse(tmp.begin(),tmp.end());
    for(auto v : tmp) printf("%d\n",v);
}   
int main() {
    solve();
    //system("pause");
    return 0;
}
View Code

F:題意沒讀懂,好像是個不太難的染色dp

G:考慮對於每一個Y,令第i個Y的B[i]表示pos[i] - i.

每次操作就等價於每次對B[i],+1或者-1

那麼對於一段連續的Y,如果要讓他們連在一起,就是讓一段B都相等。

很顯然這裡可以得出B[i] - B[i -1] >= 0。也就表示B是一個遞增序列。

考慮一個序列{a1,a2,....an}要讓所以的數到一個數的差值和的絕對值最小,顯然那個目標數應該是中位數。

那麼這個總共需要的步數也就是$\sum_{i = L}^{r} |b[i] - mid|$

所以我們可以列舉一個左端點,然後二分長度,中間的判斷可以用字首和優化(因為B肯定遞增)。

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef long double ld;
typedef pair<int,int> pii;
const int N = 2e5 + 5;
const int M = 5e6 + 5;
const LL Mod = 1e9 + 7;
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
inline long long ADD(long long x,long long y) {
    if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
    return (x + y) % Mod;
}
inline long long MUL(long long x,long long y) {
    if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
    return x * y % Mod;
}
inline long long DEC(long long x,long long y) {
    if(x - y < 0) return (x - y + Mod) % Mod;
    return (x - y) % Mod;
}

string s;
LL k,pre[N];
int b[N],n;
bool check(int L,int len) {
    int r = L + len - 1;
    int mid = L + len / 2;
    LL ma = pre[r] - pre[mid] - 1LL * (r - mid) * b[mid];
    ma += 1LL * (mid - L) * b[mid] - (pre[mid - 1] - pre[L - 1]);
    if(ma <= k) return true;
    else return false;
}
void solve() {
    cin >> s >> k;  
    n = s.size();
    int tot = 0;
    for(int i = 1;i <= n;++i) {
        if(s[i - 1] == 'Y') {
            ++tot;
            b[tot] = i - tot;
        }
    }
    int ans = 0;
    for(int i = 1;i <= tot;++i) pre[i] = pre[i - 1] + b[i];
    for(int i = 1;i <= tot;++i) {
        int L = 1,r = tot - i + 1;
        while(L <= r) {
            int mid = (L + r) >> 1;
            if(check(i,mid)) {
                ans = max(ans,mid);
                L = mid + 1;   
            }
            else r = mid - 1;
        }
    }
    printf("%d\n",ans);
}   
int main() {
    //int _;
    //for(scanf("%d",&_);_;_--) 
        solve();
    system("pause");
    return 0;
}
View Code