目录
题目
A. Three Doors
题意:
一共三扇门, 其中两个后面有一把钥匙,钥匙能开对应的门, 开始的时候给你一把钥匙, 问你能不能通过这把钥匙开所有的门.
思路:
题意描述的不太开, 总之就是个简单的模拟操作. map记录下每个门后面对应的钥匙, 再检查是否能通过给你的钥匙开所有的门即可.
code:
/**
* author: CurleyD
* created: 07.22.2022 10:26:48
**/
#include <bits/stdc++.h>
using namespace std;
#define fastIO ios::sync_with_stdio(false); cin.tie(nullptr);
#define debug cout<<"\nStop Here\n"; return;
#define per(i,a,n) for(int i=n;i>=a;i--)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define eb emplace_back
#define pb push_back
#define se second
#define fi first
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const ll MOD = 1000000007;
const db eps = 1e-6;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
//#define int long long
//head
int T = 1, n, m;
void solve() {
cin >> n;
map<int,int> mp;
for (int i = 1; i <= 3; i++) {
int x;
cin >> x;
mp[i] = x;
}
int t = mp[n];
int cnt = 1;
while (cnt < 3 && t != 0) {
cnt ++;
t = mp[t];
}
if (cnt == 3)
cout << "YES\n";
else
cout << "NO\n";
}
signed main() {
fastIO
cin >> T;
while(T--) {solve();}
return 0;
}
B. Also Try Minecraft
题意:
从1~n按编号给你n个高度, 从高度低的到高度高的需要花费
.现在给你m个查询, 问你每次从
走
的需要花费多少.
思路:
会爆int, 注意开long long (我#define int long long 了)
开始想着直接一个前缀和就可以解决, 但看到样例有从右向左走的, 联想到逆序的时候又需要一个新的前缀和, 因此两个前缀和扫一遍, 查询的时候分成 1)l < r 2)l > r 来算即可.
code:
/**
* author: CurleyD
* created: 07.22.2022 10:26:48
**/
#include <bits/stdc++.h>
using namespace std;
#define fastIO ios::sync_with_stdio(false); cin.tie(nullptr);
#define debug cout<<"\nStop Here\n"; return;
#define per(i,a,n) for(int i=n;i>=a;i--)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define eb emplace_back
#define pb push_back
#define se second
#define fi first
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const ll MOD = 1000000007;
const db eps = 1e-6;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
#define int long long
//head
int T = 1, n, m;
void solve() {
cin >> n >> m;
vector<int> a(n + 1);
vector<int> sum1(n + 1);
vector<int> sum2(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 2; i <= n; i++) {
if (a[i] > a[i-1])
sum1[i] = a[i] - a[i-1];
sum1[i] += sum1[i-1];
}
for (int i = n - 1; i >= 1; i--) {
if (a[i] > a[i+1])
sum2[i] = a[i] - a[i+1];
sum2[i] += sum2[i+1];
}
while (m--) {
int l, r;
cin >> l >> r;
if (l > r) {
cout << sum1[l] - sum1[r] << endl;
}
else {
cout<<sum2[l] - sum2[r]<<endl;
}
}
}
signed main() {
fastIO
// cin >> T;
while(T--) {solve();}
return 0;
}
C. Recover an RBS
题意:
对于给出的由"?", "(", ")"构成的字符串, 问你是否存在唯一的正则括号序列? (关于正则括号序列regular bracket sequence详细的请自行题干)
思路:
贪心
做的时候没什么想法, 后来看了群里大佬的题解, 理解了七七八八. 唯一性证明不太理解
我所想到的对保证唯一性的方法就是:对于每个问号都变成左括号去和未匹配的右括号配对, 进而保证一定是最优的从而不满足这个条件的就不算是YES, 进而推出唯一性?
用cnt记录问号数量, dep记录当前有的未匹配的左/右括号数量, 大于0表是当前有未匹配的左括号, 小于0表示当前有未匹配的右括号. 我们for遍历一下串s, 会有以下情况
1)遇到左括号那么dep ++.
2)遇到右括号dep -- 在这个条件中可能遇到dep < 0即却左括号, 那么我们把问号转化成左括号cnt --, 进而让dep ++, 消除了未配对的右括号(似乎这里保证了最优/唯一性)
3)问号 cnt ++
4)dep = 0 && cnt = 1, 已经有的左右括号全部匹配, 但其中有这问号. 那么这个问号一定不能是右括号! 只能是左括号, 因此我们可以直接将其转化成左括号! cnt -- dep ++
code:
/**
* author: CurleyD
* created: 07.22.2022 12:20:38
**/
#include <bits/stdc++.h>
using namespace std;
#define fastIO ios::sync_with_stdio(false); cin.tie(nullptr);
#define debug cout<<"\nStop Here\n"; return;
#define per(i,a,n) for(int i=n;i>=a;i--)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define eb emplace_back
#define pb push_back
#define se second
#define fi first
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const ll MOD = 1000000007;
const db eps = 1e-6;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
//#define int long long
//head
int T = 1, n, m;
void solve() {
int dep = 0;
string s;
cin >> s;
int cnt = 0;
for (auto c : s) {
if (c == '(')
dep ++;
else if (c == ')'){
dep --;
if (dep < 0) {
dep ++;
cnt --;
}
}
else
cnt ++;
if (dep == 0 && cnt == 1)
dep ++, cnt = 0;
}
if (abs(dep) == cnt)
cout << "YES\n";
else
cout << "NO\n";
}
signed main() {
fastIO
cin >> T;
while(T--) {solve();}
return 0;
}
D. Rorororobot
待补. 区间查询最值, 需要用到ST表/线段树. 等到补了这个知识点回来搞D.
总结
昨天睡着了, 没在赛时打, 早上起来补掉了但打了估计也是2题orz, A,B很签就是实现的慢了点, 半小时才出这俩, 后来C实在没思路去吃饭了... 感觉问题在于, 有了想法, 不能在最快的时间用最短的/最精确的代码实现. 有的时候还会明知道自己想的不对, 但一路走到黑... 思维需要更跳脱一些, 像多校那几个签到不要明明有能力写出, 但卡在一些不该卡的方面上. 下场CF争取按时打. (不过这两天恢复了正常作息早7晚10, 好耶LoL) 希望下场多校都1A签到, 自己能多签几个...