其实还在补题,F死活看不懂,G更难了。
其实这次比较可惜,E题我当时其实已经找到规律了,可惜样例都是奇数,我的偶数情况出了问题我都没有发现,错失上分良机,不过前面的题手速还算可以,没掉分还是比较高兴的。开学之前我必然是上绿名的,争取一下1400+吧(无端热血)
意思就是给你一个长度为三的字符串,让你忽略大小写判断字符串是不是"yes",是的话输出YES,不是输出“NO"
// Problem: A. YES or YES?
// Contest: Codeforces - Codeforces Round #806 (Div. 4)
// URL: https://codeforces.com/contest/1703/problem/0
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
string str;
cin >> str;
if ((str[0] == 'Y' || str[0] == 'y') && (str[1] == 'E' || str[1] == 'e') && (str[2] == 'S' || str[2] == 's'))
{
puts("YES");
}
else
puts("NO");
}
}
B Codeforces (Unofficial mirror site, accelerated for Chinese users)
B题意思就是说给你一个字符串,里面的字母第一次出现就加2,后面再出现就加1,没什么好说的,打个标记就可以了。
#include <bits/stdc++.h>
using namespace std;
int vis[26];
int main()
{
int t;
cin >> t;
while (t--)
{
string str;
int n;
cin >> n;
cin >> str;
memset(vis, 0, sizeof(vis));
int count = 0;
for (int i = 0; i < n; i++)
{
if (!vis[str[i] - 'A'])
{
vis[str[i] - 'A'] = 1;
count += 2;
}
else
count += 1;
}
printf("%d\n", count);
}
}
C Codeforces (Unofficial mirror site, accelerated for Chinese users)
模拟题,跟着题目做就好了。
// Problem: C. Cypher
// Contest: Codeforces - Codeforces Round #806 (Div. 4)
// URL: https://codeforces.com/contest/1703/problem/C
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
int a[105];
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
for (int i = 1; i <= n; i++)
{
int num;
cin >> num;
string s;
cin >> s;
for (int j = 0; j < num; j++)
{
if (s[j] == 'D')
{
a[i]++;
if (a[i] == 10)
a[i] = 0;
}
if (s[j] == 'U')
{
a[i]--;
if (a[i] == -1)
a[i] = 9;
}
}
}
for (int i = 1; i <= n; i++)
{
if (i == n)
printf("%d\n", a[i]);
else
printf("%d ", a[i]);
}
}
}
D Codeforces (Unofficial mirror site, accelerated for Chinese users)
意思就是给你一堆字符串,如果某个字符串可以被其他任意两个字符串相连得到(两个字符串可以相同),那么就把这个字符串对应的数改为1,最后输出01序列。
又见map啊,真好用。
之所以要使用map,是为了快速查找某个字符串是否存在。
遍历一遍字符串数组,然后对于每个字符串求出它的所有分割的左、右子串。然后到map里面查找是否存在,都存在就修改。
对于寻找左右字串可以用string类的成员函数substr()实现,substr()是用于复制子串的函数。
// Problem: D. Double Strings
// Contest: Codeforces - Codeforces Round #806 (Div. 4)
// URL: https://codeforces.com/contest/1703/problem/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
string a[N];
int b[N];
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
int ok = 0;
map<string, int> mp;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
mp[a[i]]++;
}
for (int i = 1; i <= n; i++)
{
ok = 0;
for (int j = 1; j < a[i].size(); j++)
{
string l = a[i].substr(0, j);
string r = a[i].substr(j, a[i].size());
if (mp[l] && mp[r])
{
ok = 1;
break;
}
}
cout << ok;
}
puts("");
}
}
E Codeforces (Unofficial mirror site, accelerated for Chinese users)
这题就是说一个方阵有0或1构成,现在你可以把0变成1或者把1变成0,问你构造一个旋转90度,180度270度都不变的方阵的最小操作数,注意是3种情况都不变,旋转会使方阵上的四个点产生关联,要构造这样一个方阵的话,就必须这四个点的值都不变。所以如果是0多,那就都变成0,如果是1多,那就都变成1。由于这四个点与中心点的相对关系是容易确定的,遍历这个存储方阵的二维数组,对于每个点都寻找与它有关联的其他点,然后进行修改操作,还可以通过标记来实现不会重复寻找。特别要注意的是如果方阵的边长是偶数,那么它的中心点就不是整数了,昨天就死在这里了。
代码写的巨丑,但是逻辑应该是比较容易看出来的。
// Problem: E. Mirror Grid
// Contest: Codeforces - Codeforces Round #806 (Div. 4)
// URL: https://codeforces.ml/contest/1703/problem/E
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
char a[105][105];
int vis[105][105];
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
memset(a, 0, sizeof(a));
memset(vis, 0, sizeof(vis));
if (n == 1)
{
int num;
cin >> num;
puts("0");
}
else
{
int count = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> a[i][j];
a[i][j] -= '0';
}
getchar();
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (!vis[i][j] && n % 2)
{
int x = i - (n + 1) / 2;
int y = j - (n + 1) / 2;
if (a[i][j] + a[(n + 1) / 2 - y][(n + 1) / 2 + x] + a[(n + 1) / 2 + y][(n + 1) / 2 - x] +
a[(n + 1) / 2 - x][(n + 1) / 2 - y] >=
2)
{
if (a[i][j] != 1)
{
a[i][j] = 1;
count++;
}
if (a[(n + 1) / 2 + y][(n + 1) / 2 - x] != 1)
{
a[(n + 1) / 2 + y][(n + 1) / 2 - x] = 1;
count++;
}
if (a[(n + 1) / 2 - x][(n + 1) / 2 - y] != 1)
{
a[(n + 1) / 2 - x][(n + 1) / 2 - y] = 1;
count++;
}
if (a[(n + 1) / 2 - y][(n + 1) / 2 + x] != 1)
{
a[(n + 1) / 2 - y][(n + 1) / 2 + x] = 1;
count++;
}
}
else
{
if (a[i][j] != 0)
{
a[i][j] = 0;
count++;
}
if (a[(n + 1) / 2 + y][(n + 1) / 2 - x] != 0)
{
a[(n + 1) / 2 + y][(n + 1) / 2 - x] = 0;
count++;
}
if (a[(n + 1) / 2 - x][(n + 1) / 2 - y] != 0)
{
a[(n + 1) / 2 - x][(n + 1) / 2 - y] = 0;
count++;
}
if (a[(n + 1) / 2 - y][(n + 1) / 2 + x] != 0)
{
a[(n + 1) / 2 - y][(n + 1) / 2 + x] = 0;
count++;
}
}
vis[i][j] = 1;
vis[(n + 1) / 2 - y][(n + 1) / 2 + x] = 1;
vis[(n + 1) / 2 + y][(n + 1) / 2 - x] = 1;
vis[(n + 1) / 2 - x][(n + 1) / 2 - y] = 1;
}
if (!vis[i][j] && n % 2 == 0)
{
double cx = (n + 1) / 2 + 0.5;
double cy = (n + 1) / 2 + 0.5;
double x = i - cx;
double y = j - cy;
if (a[i][j] + a[int(cx - y)][int(cy + x)] + a[int(cx + y)][int(cx - x)] +
a[int(cx - x)][int(cx - y)] >=
2)
{
if (a[i][j] != 1)
{
a[i][j] = 1;
count++;
}
if (a[int(cx + y)][int(cx - x)] != 1)
{
a[int(cx + y)][int(cx - x)] = 1;
count++;
}
if (a[int(cx - x)][int(cx - y)] != 1)
{
a[int(cx - x)][int(cx - y)] = 1;
count++;
}
if (a[int(cx - y)][int(cx + x)] != 1)
{
a[int(cx - y)][int(cx + x)] = 1;
count++;
}
}
else
{
if (a[i][j] != 0)
{
a[i][j] = 0;
count++;
}
if (a[int(cx + y)][int(cx - x)] != 0)
{
a[int(cx + y)][int(cx - x)] = 0;
count++;
}
if (a[int(cx - x)][int(cx - y)] != 0)
{
a[int(cx - x)][int(cx - y)] = 0;
count++;
}
if (a[int(cx - y)][int(cx + x)] != 0)
{
a[int(cx - y)][int(cx + x)] = 0;
count++;
}
}
vis[i][j] = 1;
vis[int(cx - y)][int(cx + x)] = 1;
vis[int(cx + y)][int(cx - x)] = 1;
vis[int(cx - x)][int(cx - y)] = 1;
}
}
}
cout << count << endl;
}
}
}
F和G题目前还不会,但是我是一定要补的!
官方题解是二分lower_bound()做的,实在是没懂为什么是lower_bound()
后来看别人题解,才弄懂一种前缀和数组的做法。
首先题目条件是要满足ai<i<aj<j,那么我们在输入a数组的时候就可以判断一下,如果满足ai<i则将其对应位置置为1,然后对这个序列求前缀和构造前缀和数组s,然后我们可以发现s[a[j]-1]就是满足i<aj的个数,对s[a[j]-1]求和即可。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int a[N], s[N];
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
long long ans = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
if (a[i] < i)
{
s[i] = s[i - 1] + 1;
}
else
{
s[i] = s[i - 1];
}
}
for (int j = 1; j <= n; j++)
{
if (a[j] < j && a[j] - 1 >= 1)
{
ans += s[a[j] - 1];
}
}
cout << ans << endl;
}
}