比赛名称:UNIQUE VISION Programming Contest 2022 Winter(AtCoder Beginner Contest 283)
比赛链接:AtCoder Beginner Contest 283
A - Power
题意:
求A^B(1<=A,B<=9)
要注意这个int强制转换,不然9^9输出结果时387420489,会wa,QAQ~
#include <bits/stdc++.h>
using namespace std;
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
cout << (int)pow(n, m) << "\n";
return 0;
}
B - First Query Problem
题意:
给定一个数组a和 q个操作
- 1 k x ,ak = x
- 2 k ,输出ak
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 6;
int a[N];
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
int q, x, v;
cin >> q;
while(q--){
int op;
cin >> op;
if(op == 2) {
cin >> x;
cout << a[x] << "\n";
}else{
cin >> x >> v;
a[x] = v;
}
}
return 0;
}
C - Cash Register
题意:
有一个收银机,有11个键。00,0,1,2,3,4,5,6,7,8和9。收银机最初显示0。每当他输入00键时,显示的数字就会乘以100;每当他输入其他键时,显示的数字就会乘以10,然后再加上键上的数字。高桥想让收银机显示一个整数S,至少需要多少次按键才能使它显示S?
思路:
按字符串处理,如果遇到连续的00只需要一次操作即可,其他也都是一次操作
写得有点麻烦了~
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s;
cin >> s;
int ans = 1;
for(int i = 1; i < s.size();){
if(s[i] != '0') ans ++, i++;
else{
if(s[i + 1] == '0' && i + 1 < s.size()) ans ++, i+=2;
else ans++, i++;
}
}
cout << ans << "\n";
return 0;
}
D - Scope
题意:
一共有11中关键词: 00,0,1,2,3,4,5,6,7,8,9。给出一个数字,求这个数字由多少个关键词组成?
思路:
用模拟栈存每个离)最近的(,当遇到)就把括号中的小写字母全部删去
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s;
cin >> s;
vector<int> p;
vector<int> C;
vector<bool> vis(30, false);
bool ok = true;
int f = 0;
for(int i = 0; i < s.size(); i++){
if(s[i] == '(') p.push_back(i);
else if(s[i] == ')'){
int k = p.back();
p.pop_back();
while(!C.empty() && C.back() > k){
vis[s[C.back()] - 'a'] = false;
C.pop_back();
}
}else{
if(vis[s[i] - 'a']){
ok = false;
break;
}
vis[s[i] - 'a'] = true;
C.push_back(i);
}
}
cout << (ok ? "Yes\n" : "No\n");
return 0;
}
E - Don't Isolate Elements
题意:
给一个01矩阵,每次可以翻转某行的01,问最少的操作次数使得,没有一个位置的上下左右都与其不同
思路:
动态规划
每行都有且只有两种状态,翻转或不翻转,所以定义状态表示,前i行已经确定,第i-1行的状态位j,第i行状态为k时使合法的操作数
状态转移方程:
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, m;
int a[N][N], f[N][2][2];
bool check(int i, int x, int y, int z){
for (int j = 1; j <= m; j++){
if (a[i][j] != a[i][j - 1] && a[i][j] != a[i][j + 1] && (a[i][j] ^ y) != (a[i - 1][j] ^ x) && (a[i][j] ^ y) != (a[i + 1][j] ^ z)){
return 0;
}
}
return 1;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
memset(a, -1, sizeof a);
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[1][0][0] = 0;
f[1][0][1] = 1;
for (int i = 2; i <= n; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < 2; k++)
for (int l = 0; l < 2; l++)
if (check(i - 1, j, k, l))
f[i][k][l] = min(f[i][k][l], f[i - 1][j][k] + l);
int ans = 0x3f3f3f3f;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < 2; k++)
if (check(n, i, j, k))
ans = min(ans, f[n][i][j]);
cout << (ans == 0x3f3f3f3f ? -1 : ans) << "\n";
return 0;
}
F - Permutation Distance
题意:
给一个排列p,求d数组
其中d数组满足
思路:
由上总共四种情况
所以我们可以发现可以用一个数据结构去维护,根据不同的限制条件,最后算四种情况下的最小值
这里我们选择树状数组来维护,具体见代码。
AcCode:
#include <bits/stdc++.h>
#define lowbit(x) x & (-x)
#define inf 0x3f3f3f3f
using namespace std;
const int N = 1e6 + 9;
int n;
int tr[N], p[N], ans[N];
void add(int x, int v){
for(int i = x; i <= n; i += lowbit(i))
tr[i] = min(tr[i], v);
}
int query(int x){
int ans = inf;
for(int i = x; i; i -= lowbit(i))
ans = min(ans, tr[i]);
return ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for(int i = 1; i <= n; i++) cin >> p[i], ans[i] = inf;
memset(tr, 0x3f, sizeof tr);
for(int i = 1; i <= n; i++){
ans[i] = min(ans[i], query(p[i]) + p[i] + i);
add(p[i], -p[i] - i);
}
memset(tr, 0x3f, sizeof tr);
for(int i = 1; i <= n; i++){
ans[i] = min(ans[i], query(n + 1 - p[i]) - p[i] + i);
add(n + 1 - p[i], p[i] - i);
}
memset(tr, 0x3f, sizeof tr);
for(int i = n; i >= 1; i--){
ans[i] = min(ans[i], query(p[i]) + p[i] - i);
add(p[i], -p[i] + i);
}
memset(tr, 0x3f, sizeof tr);
for(int i = n; i >= 1; i--){
ans[i] = min(ans[i], query(n + 1 - p[i]) - p[i] - i);
add(n + 1 - p[i], p[i] + i);
}
for(int i = 1; i <= n; i++) cout << ans[i] << " \n"[i == n];
return 0;
}
G题,EX题嗷嗷待补~QAQ~摸了