AtCoder Beginner Contest 283(A~F)

A

a,b=map(int,input().split())
print(pow(a,b))

B

n=int(input())
a=list(map(int,input().split()))
q=int(input())
for i in range(q):
    op=list(map(int,input().split()))
    if op[0]==1:
        a[op[1]-1]=op[2]
    else:
        print(a[op[1]-1])

C

两个连续的00看作一个即可

S =list(input())

ans = len(S)

for i in range(1,len(S)):
    if S[i-1]=="0" and S[i]=="0":
        S[i]="x"
        ans-=1
print(ans)

D

一开始看错题了,不需要字符串最后为空,只需要判断两个括号之间的字母是否重复即可

#include <bits/stdc++.h>
int _ = 0, Case = 1;
#define int long long
using namespace std;
#define all(v) begin(v),end(v)
#define nline '\n'
#define SZ(v) (int) v.size()

const int N = 300010;
char s[N];
void solve(int Case) {
    cin >> s + 1;
    int n = strlen(s + 1);
    map<int, int> vis;
    stack<map<char, int>>stk;
    for (int i = 1; i <= n; i++) {
        char c = s[i];
        if (stk.size()) {
            auto t = stk.top();
            if (c == ')') {
                stk.pop();
                for (char j = 'a'; j <= 'z'; j++) {
                    if (t[j]) vis[j] = 0;
                }
            } else if (c == '(') {
                map<char, int> tem;
                stk.push(tem);
            } else {
                if (vis[c]) {
                    cout << "No" << nline;
                    return;
                }
                stk.pop();
                t[c] = 1;
                vis[c] = 1;
                stk.push(t);
            }
        } else {
            if (c == ')') {
            } else if (c == '(') {
                map<char, int> tem;
                stk.push(tem);
            } else {
                if (vis[c]) {
                    cout << "No" << nline;
                    return;
                }
                vis[c] = 1;

            }
        }
    }
    cout << "Yes" << nline;




}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);


//   for (cin>>_, Case = 1; Case <= _; Case++)
    solve(Case);

    return 0;
}

E

动态规划,f[i][j][k],表示当前操作到第i行,并且第i行状态时j,i-1的状态时k,转移就是f[i][j][k]=f[i-1][k][kk],kk是第i-2行的状态;

#include <bits/stdc++.h>
int _ = 0, Case = 1;
#define int long long
using namespace std;
#define all(v) begin(v),end(v)
#define nline '\n'
#define SZ(v) (int) v.size()
const int N = 2020;
int a[N][N];
int n, m;
int f[N][2][2];
bool check(int c, int x, int y, int z) {
    c--;
    if (c == 0) {
        return true;
    } else if (c == 1) {

        for (int i = 1; i <= m; i++) {
            bool ok = false;
            if ((a[c][i]^y) == (a[c + 1][i]^x)) ok = true;
            if (i + 1 <= m and a[c][i] == a[c][i + 1]) ok = true;
            if (i - 1 >= 1 and a[c][i] == a[c][i - 1]) ok = true;
            if (!ok) return false;
        }
        return true;
    } else if (c != n - 1) {
        for (int i = 1; i <= m; i++) {
            bool ok = false;
            if (((a[c][i]^y) == (a[c - 1][i]^z)) or ((a[c][i]^y) == (a[c + 1][i]^x))) ok = true;
            if (i + 1 <= m and a[c][i] == a[c][i + 1]) ok = true;
            if (i - 1 >= 1 and a[c][i] == a[c][i - 1]) ok = true;
            if (!ok) return false;
        }
        return true;
    } else {
        c++;
        for (int i = 1; i <= m; i++) {
            bool ok = false;
            if ((a[c][i]^x) == (a[c - 1][i]^y)) ok = true;
            if (i + 1 <= m and a[c][i] == a[c][i + 1]) ok = true;
            if (i - 1 >= 1 and a[c][i] == a[c][i - 1]) ok = true;
            if (!ok) return false;
        }
        return true;
    }
}
void solve(int Case) {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> a[i][j];
        }
    }

    memset(f, 0x3f, sizeof f);
    f[0][0][0] = 0;
    f[0][1][0] = 0;
    f[0][1][1] = 0;
    f[0][0][1] = 0;
    for (int i = 1; i <= n; i++) {
        for (int x = 0; x < 2; x++) {
            for (int y = 0; y < 2; y++) {
                for (int z = 0; z < 2; z++) {
                    if (check(i, x, y, z)) {
                        f[i][x][y] = min(f[i - 1][y][z] + x, f[i][x][y]);
                    }
                }
            }
        }
    }
    int res = 1e9;
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            res = min(res, f[n][i][j]);
        }
    }
    if (res == 1e9) res = -1;
    cout << res << nline;




}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);


//   for (cin>>_, Case = 1; Case <= _; Case++)
    solve(Case);

    return 0;
}

F

假如只看一边,那么就是对于前i个,把数字分为大于x和小于x,那么结果分别是p[j]-j-x+i,-p[j]-j+x+i,这一步可以使用权值线段树完成。

#include <bits/stdc++.h>
int _ = 0, Case = 1;
#define int long long
using namespace std;
#define all(v) begin(v),end(v)
#define nline '\n'
#define SZ(v) (int) v.size()
const int N = 200010;
int p[N];
#define ls(x) x<<1
#define rs(x) x<<1 |1
struct tree {
    int l, r;
    int aa;
    int bb;
};
struct Segment_Tree {
    tree tr[N << 2];
    int pos[N];
    void pushup(tree &p, tree &l, tree &r) {
        p.aa = min(l.aa, r.aa);
        p.bb = min(l.bb, r.bb);
    }
    void pushup(int p) {
        pushup(tr[p], tr[ls(p)], tr[rs(p)]);
    }
    void build(int p, int l, int r) {
        if (l == r) {
            tr[p] = {l, r, 1000000000, 1000000000};
            pos[l] = p;
        }
        else {
            tr[p] = {l, r};
            int mid = l + r >> 1;
            build(ls(p), l, mid);
            build(rs(p), mid + 1, r);
            pushup(p);
        }
    }
    void modifyA(int p, int x, int y) {
        p = pos[x];
        tr[p].aa = y;
        for (; p >>= 1;) pushup(p);
    }
    void modifyB(int p, int x, int y) {
        p = pos[x];
        tr[p].bb = y;
        for (; p >>= 1;) pushup(p);
    }
    tree query(int p, int l, int r) {
        if (tr[p].l >= l and tr[p].r <= r) return tr[p];
        int mid = tr[p].l + tr[p].r >> 1;
        if (r <= mid) return query(ls(p), l, r);
        else if (l > mid) return query(rs(p), l, r);
        else {
            tree ret;
            auto left = query(ls(p), l, r);
            auto right = query(rs(p), l, r);
            pushup(ret, left, right);
            return ret;
        }
    }
};
Segment_Tree ST;
int ans[N];
void solve(int Case) {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> p[i], ans[i] = 1e9;
    ST.build(1, 1, n);
    //xiao x+i-(p[j]+j),aa=-p[j]-j
    //da (p[j]-j)+i-x,bb=p[j]-j;    
    for (int i = 1; i <= n; i++) {
        int x = p[i];
        int t = ST.query(1, 1, x).aa;
        int t1 = ST.query(1, x, n).bb;
        ans[i] = min({ans[i], x + i+t, t1 + i - x});
        ST.modifyA(1, x, -x - i);//xiao
        ST.modifyB(1, x, x - i);//da
    }
    ST.build(1, 1, n);
    reverse(p + 1, p + 1 + n);
    for (int i = 1; i <= n; i++) {
        int x = p[i];
        int t = ST.query(1, 1, x).aa;
        int t1 = ST.query(1, x, n).bb;
        ans[n-i+1] = min({ans[n-i+1], x + i+t, t1 + i - x});
        ST.modifyA(1, x, -x - i);//xiao
        ST.modifyB(1, x, x - i);//da
    }
    for (int i = 1; i <= n; i++) {
        cout << ans[i] << ' ';
    }
    cout << nline;




}

signed main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);


//   for (cin>>_, Case = 1; Case <= _; Case++)
    solve(Case);

    return 0;
}
posted @ 2022-12-25 15:33  指引盗寇入太行  阅读(66)  评论(0编辑  收藏  举报