【AtCoder】AISing Programming Contest 2019

本来以为是1199rated的。。仔细一看发现是1999,所以就做了一下

这场涨分很轻松啊。。。为啥又没打

等pkuwc考完我一定打一场atcoder(咕咕咕,咕咕咕,咕咕咕咕咕咕咕~)

但是其实我思维速度上真的有点不行。。。

A - Bulletin Board

输出\((N - W + 1)(N - H + 1)\)

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(‘ ‘)
#define enter putchar(‘\n‘)
#define MAXN 20000005
#define eps 1e-10
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < ‘0‘ || c > ‘9‘) {
        if(c == ‘-‘) f = -1;
        c = getchar();
    }
    while(c >= ‘0‘ && c <= ‘9‘) {
        res = res * 10 + c - ‘0‘;
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar(‘-‘);}
    if(x >= 10) {
        out(x / 10);
    }
    putchar(‘0‘ + x % 10);
}
int N,H,W;
void Solve() {
    read(N);read(H);read(W);
    out(1LL * (N - H + 1) * (N - W + 1));enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

B - Contests

统计这三个区间的个数,输出最小值

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(‘ ‘)
#define enter putchar(‘\n‘)
#define MAXN 20000005
#define eps 1e-10
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < ‘0‘ || c > ‘9‘) {
        if(c == ‘-‘) f = -1;
        c = getchar();
    }
    while(c >= ‘0‘ && c <= ‘9‘) {
        res = res * 10 + c - ‘0‘;
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar(‘-‘);}
    if(x >= 10) {
        out(x / 10);
    }
    putchar(‘0‘ + x % 10);
}
int N;
int P[105],A,B;
int cnt[3];
void Solve() {
    read(N);read(A);read(B);
    for(int i = 1 ; i <= N ; ++i) {
        read(P[i]);
        if(P[i] <= A) ++cnt[0];
        else if(P[i] <= B) ++cnt[1];
        else cnt[2]++;
    }
    out(min(min(cnt[0],cnt[1]),cnt[2]));enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

C - Alternating Path

相邻的黑白格子之间有边,答案是每个联通块里的黑白点个数乘积之和

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(‘ ‘)
#define enter putchar(‘\n‘)
#define MAXN 20000005
#define eps 1e-10
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < ‘0‘ || c > ‘9‘) {
        if(c == ‘-‘) f = -1;
        c = getchar();
    }
    while(c >= ‘0‘ && c <= ‘9‘) {
        res = res * 10 + c - ‘0‘;
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar(‘-‘);}
    if(x >= 10) {
        out(x / 10);
    }
    putchar(‘0‘ + x % 10);
}
int H,W,a[405][405],cnt[2];
char s[405][405];
bool vis[405][405];
int dx[] = {0,1,0,-1};
int dy[] = {1,0,-1,0};
bool in_range(int x,int y) {
    return x >= 1 && x <= H && y >= 1 && y <= W;
}
void dfs(int x,int y) {
    cnt[a[x][y]]++;vis[x][y] = 1;
    for(int k = 0 ; k < 4 ; ++k) {
        int tx = x + dx[k],ty = y + dy[k];
        if(in_range(tx,ty)) {
            if(!vis[tx][ty] && a[tx][ty] != a[x][y]) {
                dfs(tx,ty);
            }
        }
    }
}
void Solve() {
    read(H);read(W);
    for(int i = 1 ; i <= H ; i++) {
        scanf("%s",s[i] + 1);
        for(int j = 1 ; j <= W ; ++j) {
            if(s[i][j] == ‘#‘) a[i][j] = 1;
            else a[i][j] = 0;
        }
    }
    int64 ans = 0;
    for(int i = 1 ; i <= H ; ++i) {
        for(int j = 1 ; j <= W ; ++j) {
            if(!vis[i][j]) {
                cnt[1] = 0;cnt[0] = 0;
                dfs(i,j);
                ans += 1LL * cnt[1] * cnt[0];
            }
        }
    }
    out(ans);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

D - Nearest Card Game

先二分一个k,使得\([x - k,x + k]\)区间里的数的个数小于等于\((x + k,\infty)\)里的数,且\(k\)最大,先把\([x - k,x + k]\)这些区间里这么多数两个人分别取走

然后从这个状态暴力模拟(大于x的数不会超过两个了),使得所有的数都小于x,剩下的就是交替一个一个取了,可以用一个前缀和预处理出来

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(‘ ‘)
#define enter putchar(‘\n‘)
#define MAXN 100005
#define eps 1e-10
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < ‘0‘ || c > ‘9‘) {
        if(c == ‘-‘) f = -1;
        c = getchar();
    }
    while(c >= ‘0‘ && c <= ‘9‘) {
        res = res * 10 + c - ‘0‘;
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar(‘-‘);}
    if(x >= 10) {
        out(x / 10);
    }
    putchar(‘0‘ + x % 10);
}
int N,Q;
int64 A[MAXN],sum[MAXN],b[MAXN];
pii Calc(int64 l,int64 r) {
    int a = lower_bound(A + 1,A + N + 1,l) - A;
    int b = upper_bound(A + 1,A + N + 1,r) - A - 1;
    return mp(a,b);
}
int64 Process(int64 x) {
    if(x >= A[N]) return sum[N];
    int64 L = 0,R = A[N];
    int p = lower_bound(A + 1,A + N + 1,x) - A;
    while(L < R) {
        int64 mid = (L + R + 1) >> 1;
        pii t = Calc(x - mid,x + mid);
        int rem = N - p + 1 - (t.se - p + 1);
        if(rem >= t.se - t.fi + 1) L = mid;
        else R = mid - 1;
    }
    pii t = Calc(x - L,x + L);
    int len = t.se - t.fi + 1;
    int64 res = b[N] - b[N - len];
    int q = N - len,h0 = t.fi - 1,h1 = t.se + 1;
    while(q >= h1) {
        res += A[q];--q;
        if(h1 > q && h0 < 1) break;
        int now;
        if(h1 > q) now = h0;
        else if(h0 < 1) now = h1;
        else {
            if(x - A[h0] <= A[h1] - x) now = h0;
            else now = h1;
        }
        if(now == h1) ++h1;
        if(now == h0) --h0;
    }
    res += sum[h0];
    return res;
}
void Solve() {
    read(N);read(Q);
    for(int i = 1 ; i <= N ; ++i) read(A[i]);
    for(int i = 1 ; i <= N ; ++i) {
        sum[i] = A[i];
        if(i >= 2) sum[i] += sum[i - 2];
        b[i] = A[i] + b[i - 1];
    }
    int64 x;
    for(int i = 1 ; i <= Q ; ++i) {
        read(x);
        out(Process(x));enter;
    }
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

E - Attack to a Tree

这个直接dp就好了,\(dp[u][j][0/1]\)表示以\(u\)为根,砍断了\(j\)条边,0表示没有电脑,1表示有电脑,dp里的值就是和u联通的联通块值最小值是多少

用一个bool数组辅助记录一下这个dp状态可不可以被达到

转移的话就是树背包,\(dp[u][j][a] + dp[v][h][b] \rightarrow dp[u][j + h][a | b]\)

然后如果有父亲的话用\(dp[u][j][0]\)和\(dp[u][j][1]\)更新\(dp[u][j + 1][0]\)

没有的话就直接记录答案就行

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(‘ ‘)
#define enter putchar(‘\n‘)
#define MAXN 5005
#define eps 1e-10
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < ‘0‘ || c > ‘9‘) {
        if(c == ‘-‘) f = -1;
        c = getchar();
    }
    while(c >= ‘0‘ && c <= ‘9‘) {
        res = res * 10 + c - ‘0‘;
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar(‘-‘);}
    if(x >= 10) {
        out(x / 10);
    }
    putchar(‘0‘ + x % 10);
}
struct node {
    int to,next;
}E[MAXN * 2];
int head[MAXN],sumE;
bool vis[MAXN][MAXN][2],used[MAXN][2];
int64 dp[MAXN][MAXN][2],A[MAXN],g[MAXN][2];
int N,siz[MAXN],ans;
void add(int u,int v) {
    E[++sumE].to = v;
    E[sumE].next = head[u];
    head[u] = sumE;
}
void dfs(int u,int fa) {
    if(A[u] < 0) {
        vis[u][0][1] = 1;dp[u][0][1] = A[u];
    }
    if(A[u] > 0) {
        vis[u][0][0] = 1;dp[u][0][0] = A[u];
    }
    for(int i = head[u] ; i ; i = E[i].next) {
        int v = E[i].to;
        if(v != fa) {
            dfs(v,u);
        }
    }
    memset(used,0,sizeof(used));
    siz[u] = 1;
    for(int i = head[u] ; i ; i = E[i].next) {
        int v = E[i].to;
        if(v != fa) {
            for(int j = 0 ; j <= siz[u] + siz[v] ; ++j) used[j][0] = used[j][1] = 0;
            for(int j = 0 ; j <= siz[u] ; ++j) {
                for(int a = 0 ; a <= 1 ; ++a) {
                    if(!vis[u][j][a]) continue;
                    for(int h = 0 ; h <= siz[v] ; ++h) {
                        for(int b = 0 ; b <= 1 ; ++b) {
                            if(!vis[v][h][b]) continue;
                            if(!used[j + h][a | b]) {
                                g[j + h][a | b] = dp[u][j][a] + dp[v][h][b];
                                used[j + h][a | b] = 1;
                            }
                            else g[j + h][a | b] = min(g[j + h][a | b],dp[u][j][a] + dp[v][h][b]);
                        }
                    }
                }
            }
            for(int j = 0 ; j <= siz[u] + siz[v] ; ++j) {
                for(int a = 0 ; a <= 1 ; ++a) {
                    vis[u][j][a] = used[j][a];
                    dp[u][j][a] = g[j][a];
                }
            }
            siz[u] += siz[v];
        }
    }
    if(fa) {
        for(int j = siz[u] ; j >= 0 ; --j) {
            if(vis[u][j][1] && dp[u][j][1] < 0) {dp[u][j + 1][0] = 0;vis[u][j + 1][0] = 1;}
            if(vis[u][j][0]) {dp[u][j + 1][0] = 0;vis[u][j + 1][0] = 1;}
        }
    }
    else {
        for(int j = 0 ; j <= siz[u] ; ++j) {
            if(vis[u][j][1] && dp[u][j][1] < 0) {ans = j;break;}
            if(vis[u][j][0]) {ans = j;break;}
        }
    }
}
void Solve() {
    read(N);
    for(int i = 1 ; i <= N ; ++i) read(A[i]);
    int u,v;
    for(int i = 1 ; i < N ; ++i) {
        read(u);read(v);
        add(u,v);add(v,u);
    }
    dfs(1,0);
    out(ans);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

原文地址:https://www.cnblogs.com/ivorysi/p/10275570.html

时间: 2024-10-08 03:33:49

【AtCoder】AISing Programming Contest 2019的相关文章

【AtCoder】Tenka1 Programmer Contest 2019

Tenka1 Programmer Contest 2019 C - Stones 题面大意:有一个01序列,改变一个位置上的值花费1,问变成没有0在1右边的序列花费最少多少 直接枚举前i个都变成0即可 #include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space

【AtCoder】Dwango Programming Contest V题解

A - Thumbnail 根据题意写代码 #include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define

AtCoder AISing Programming Contest 2019 Task D. Nearest Card Game

题目分析在代码注释里. int main() { #if defined LOCAL && !defined DUIPAI ifstream in("main.in"); cin.rdbuf(in.rdbuf()); // ofstream out("main.out"); // cout.rdbuf(out.rdbuf()); #endif int n, q; scan(n, q); vi a(n); scan(a); vl sum(n); sum

[AtCoder] NIKKEI Programming Contest 2019 (暂缺F)

[AtCoder] NIKKEI Programming Contest 2019 ??本来看见这一场的排名的画风比较正常就来补一下题,但是完全没有发现后两题的AC人数远少于我补的上一份AtCoder. A - Subscribers ??首先始终 \(max = \min(A, B)\) ,\(min\) 的话如果 \(A + B \leq N\) ,那么就是 \(0\) ,否则就是 \(A + B - N\) . int n, a, b; int main() { read(n), read

2020-3-14 acm训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019 解题报告+补题报告

2020-3-15比赛解题报告+2020-3-8—2020-3-15的补题报告 2020-3-15比赛题解 训练联盟周赛Preliminaries for Benelux Algorithm Programming Contest 2019  A建筑(模拟) 耗时:3ms 244KB 建筑 你哥哥在最近的建筑问题突破大会上获得了一个奖项 并获得了千载难逢的重新设计城市中心的机会 他最喜欢的城市奈梅根.由于城市布局中最引人注目的部分是天际线, 你的兄弟已经开始为他想要北方和东方的天际线画一些想法

【AtCoder】diverta 2019 Programming Contest

diverta 2019 Programming Contest 因为评测机的缘故--它unrated了.. A - Consecutive Integers #include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define

【Atcoder】ARC 080 E - Young Maids

[算法]数学+堆 [题意]给定n个数的排列,每次操作可以取两个数按序排在新序列的头部,求最小字典序. [题解] 转化为每次找字典序最小的两个数按序排在尾部,则p1和p2的每次选择都必须满足:p1在当前序列的奇数位置,p2在当前序列的偶数位置且位于p1之后.满足条件的情况下每次找最小. 每次找到p1和p2都把序列划分为3部分,递归进行,初步想到使用归并. 进一步考虑性质,每对数字要出现必须它的上属序列的p1和p2必须出现,此外没有其他要求. 所以用优先队列维护每个序列,序列的优先级为p1,每次处理

【Atcoder】ARC083 D - Restoring Road Network

[算法]图论,最短路? [题意]原图为无向连通图,现给定原图的最短路矩阵,求原图最小边权和,n<=300. [题解]要求最小边权和下,原图的所有边一定是所连两端点的最短路. 那么现在将所有最短路作为边加入原图,考虑删边. 对于(u,v),若存在点w使得(u,v)=(u,w)+(w,v),则(u,v)可以删去.(btw,若是>则无解) 复杂度O(n^3). #include<cstdio> #include<cstring> #include<cctype>

【AtCoder】ARC082 F - Sandglass

[链接]F - Sandglass [题意]给定沙漏A和B,分别装着a和X-a的沙子,开始时A在上B在下,每秒漏1,漏完不再漏.给定n,有n个时刻ai沙漏倒转.给定m个询问,每次询问给定初值a和时刻t,求A中沙子量. [算法]数学(函数) [题解] 先不考虑时刻,令ft(a)表示沙子初值a时,当前A中的沙子数.(x轴是初值a,y轴是沙子数num) 时刻为0时,显然是一条从0出发斜率为1的直线. 若A在上,则每过1s,整段函数都下移一个单位,碰到y=0则变成平的. 若A在下,则每过1s,整段函数都