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;
}