这次的题目有点波折,简单题上连续卡坑,还是心态要放平,慎重决策后再提交
A - Conflict
思路:两个字符串,判断是否存在某位两个字符串均为o
想的时候思路很清晰,写的时候就把条件漏了,这种题都能wa也太不应该了
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false), cin.tie(nullptr);
int n;
cin >> n;
bool yes = false;
string t, a;
cin >> t >> a;
for (int i = 0; i < n; i++) {
if (t[i] == a[i] && t[i] == 'o') {
yes = true;
}
}
cout << (yes ? "Yes" : "No") << endl;
return 0;
}
/**
* 4
* xxxx
* xxxx
* No
*/
B - Citation
思路:给定数组,要找出一个最大的数x,使得数组中大于x的数不小于x个。
思路也很清晰,给数组排个序,然后寻找a[i]<i+1条件即为不满足条件的第一个数,那么i就是最终要找的值。
连wa三发也是生无可恋了,第一发将a[i]作为了要求的结果,后来发现其实要求的结果并不一定在数组合中。第二发针对在数组中的场景,发现a[i]=i+1的边界条件未被考虑,第三发针对找不到的场景,应该直接将结果设置为数组大小,特别是第三发wa,我深知考虑到了这种case,但却莫名其妙的想当然认为0就是这种case的正确结果,也是不理解脑子一团混乱。最终这题居然到结束都没想明白,可见有时候当局者迷,陷在里面一点点很弱智的问题都可能困住,还好及时跳过去做后面的题了,要不然结果可能更加惨不忍睹
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e2 + 5;
int main() {
ios_base::sync_with_stdio(false), cin.tie(nullptr);
int n;
cin >> n;
int a[MAXN];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
sort(a, a + n, greater<int>());
int re = n;
for (int i = 0; i < n; i++) {
if (a[i] < i + 1) {
re = i;
break;
}
}
cout << re << endl;
return 0;
}
/**
* 5
* 1 2 5 7 9
* 3
*
*
* 3
* 1 2 5
* 2
*
* 3
* 6 7 8
* 3
*/
C - Equilateral Triangle
思路:给定圆周上的点,要判断存在多少个等边三角形。那这就很简单了,首先如果周长不是3的倍数,直接返回0。再记录一下每个点位的位置,将所有点位根据模3的结果分组,每组三个数。将每组三个数的数量相乘,并将不同组的结果相加即为最终值,最后考虑一下结果可能超int,开个长整型即可。
这题其实脑子也糊了一下,一开始只记录每个点位的位置,但没统计每个位置的数量,导致怎么都出不来结果,果然还是受第二题卡顿的影响了。
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3e5 + 5;
#define ll long long
int a[MAXN];
int main() {
ios_base::sync_with_stdio(false), cin.tie(nullptr);
int l, n;
cin >> n >> l;
a[0] = 1;
int pre = 0;
for (int i = 1; i < n; i++) {
int d;
cin >> d;
pre = (pre + d) % l;
a[pre]++;
}
if (l % 3 == 0) {
ll re = 0;
int div = l / 3;
for (int i = 0; i < div; i++) {
ll current = 1;
for (int j = 0; j < 3; j++) {
int pos = div * j + i;
current *= a[pos];
}
re += current;
}
cout << re << endl;
} else {
cout << 0 << endl;
}
return 0;
}
D - String Rotation
思路:旋转字符串,寻找字符串的一个子串,将其整体想坐旋转一位,求一个最佳旋转方案,使得旋转后的字典序最小
这就是个简单的贪心,寻找子串的开始和结束位置。开始位置在首个比后一位大的地方,这样可以保证旋转后一定能让字典序减小,而且由于是首位所以一定最小。而结束位置则需要将所有比首位小的字母全都囊括进来,这样可以保证首字母被转到后面后,小的字母一定被往前移动了。
最后手动模拟一下字符串旋转即可
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
string leftRotate(string s, int st, int en) {
int len = s.size();
string newString;
if (st > 0) {
newString += s.substr(0, st);
}
newString += s.substr(st + 1, en - st - 1);
newString += s[st];
if (en < len) {
newString += s.substr(en, len - en);
}
return newString;
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
string s;
cin >> s;
for (int st = 0; st < n - 1; st++) {
if (s[st] <= s[st + 1]) {
continue;
}
int en = st + 1;
while (en < n && s[st] >= s[en]) {
en++;
}
if (en > st) {
s = leftRotate(s, st, en);
break;
}
}
cout << s << endl;
}
return 0;
}
E - Pair Annihilation
思路:在一个树中移动正负离子,树的每个路径有一定权值,要求使得所有离子全都正负中和所需要的最小能量。由于知道最终终局是所有正负离子全都中和,那么这其实移动的过程其实并不重要了,无论是正离子移动还是负离子移动,经过边消耗的能量是相等的。那么这题就从策略题降级为了模拟题。找到所有叶子节点,向上移动,直到移动到根节点。为了避免过度移动,每个节点要等待其所有子节点都移动完之后再开始移动。最后注意一下,结果可能超int,主要是因为最大携带的离子量可能高达10的8次方,因此需要开个long long。
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 5;
int x[MAXN];
bool vis[MAXN];
vector<int> uv[MAXN];
vector<int> uvw[MAXN];
int nextCount[MAXN];
ll moveResult(int now, ll re) {
int current = x[now];
bool electrons = current < 0;
if (electrons) {
current = -current;
}
vis[now] = true;
int nextSize = uv[now].size();
for (int i = 0; i < nextSize; i++) {
int nextNode = uv[now][i];
if (vis[nextNode]) {
continue;
}
re += ll(uvw[now][i]) * ll(current);
if (electrons) {
current = -current;
}
x[nextNode] += current;
nextCount[now]--;
nextCount[nextNode]--;
// cout << now << "*" << re << endl;
if (nextCount[nextNode] == 1) {
re = moveResult(nextNode, re);
}
}
return re;
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(nullptr);
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> x[i];
}
for (int i = 1; i < n; i++) {
int u, v, w;
cin >> u >> v >> w;
uv[u].push_back(v);
uv[v].push_back(u);
uvw[u].push_back(w);
uvw[v].push_back(w);
nextCount[u]++;
nextCount[v]++;
}
ll re = 0;
for (int i = 1; i <= n; i++) {
if (nextCount[i] == 1) {
re = moveResult(i, re);
}
}
cout << re << endl;
return 0;
}