A-Spell Check
检查字符串是不是满足题目要求
https://codeforces.com/contest/1722/problem/A
#include <bits/stdc++.h>
using namespace std ;
int main() {
std::ios::sync_with_stdio(false) ;
std::cin.tie(0) ;
int T ;
cin >> T ;
while (T --) {
int n ;
cin >> n ;
string s ;
cin >> s ;
map<char, int>mp ;
if (n != 5)
puts("NO") ;
else {
for (int i = 0 ; i < 5 ; i ++) {
mp[s[i]] ++ ;
}
if (mp['T'] == 1 && mp['i'] == 1 && mp['m'] == 1
&& mp['u'] == 1 && mp['r'] == 1)
puts("YES") ;
else
puts("NO") ;
mp.clear() ;
}
}
return 0 ;
}
B-Colourblindness
字符串,水
https://codeforces.com/contest/1722/problem/B
#include <bits/stdc++.h>
using namespace std ;
int main() {
// std::ios::sync_with_stdio
int T ;
cin >> T ;
while (T --) {
int n ;
cin >> n ;
string a, b ;
cin >> a ;
cin >> b ;
// cout << a << ' ' << b << '\n' ;
string tmp1 = "", tmp2 = "" ;
for (int i = 0 ; i < n ; i ++) {
if (a[i] == 'G')
tmp1 += 'B' ;
else
tmp1 += a[i] ;
}
// for(int i = 0 ; i )
for (int i = 0 ; i < n ; i ++) {
if (b[i] == 'G')
tmp2 += 'B' ;
else
tmp2 += b[i] ;
}
if (tmp1 == tmp2)
puts("YES") ;
else
puts("NO") ;
}
return 0 ;
}
C-Word Game
map,水
https://codeforces.com/contest/1722/problem/C
#include <bits/stdc++.h>
using namespace std ;
set<string>a, b, c ;
map<string, int> mp ;
int main() {
std::ios::sync_with_stdio(false) ;
std::cin.tie(0) ;
int T ;
cin >> T ;
while (T --) {
int n ;
cin >> n ;
a.clear(), b.clear(), c.clear() ;
mp.clear() ;
for (int i = 0 ; i < n ; i ++) {
string x ;
cin >> x ;
a.insert(x) ;
mp[x] ++ ;
}
for (int i = 0 ; i < n ; i ++) {
string x ;
cin >> x ;
b.insert(x) ;
mp[x] ++ ;
}
for (int i = 0 ; i < n ; i ++) {
string x ;
cin >> x ;
c.insert(x) ;
mp[x] ++ ;
}
int cnta = 0, cntb = 0, cntc = 0 ;
for (auto i : mp) {
if (i.second == 1) {
string tmp = i.first ;
if (a.count(tmp))
cnta += 3 ;
else if (b.count(tmp))
cntb += 3 ;
else
cntc += 3 ;
} else if (i.second == 2) {
string tmp = i.first ;
if (!a.count(tmp)) {
cntb += 1, cntc += 1 ;
} else if (!b.count(tmp)) {
cnta += 1, cntc += 1 ;
} else
cnta += 1, cntb += 1 ;
}
}
cout << cnta << ' ' << cntb << ' ' << cntc << '\n' ;
}
return 0 ;
}
D-Line
https://codeforces.com/contest/1722/problem/D
L表示向左看能看到的人数,R表示向右看能看到的人数,总价值等于所有人看到的人数。改变k次(k = 1 , 2 , ``` n ),每次可以把L变成R或者把R变成L,问每次改变后的最大值是多少。首先我们记录初始状态的总价值,然后对每个人把改变方向以后对于总价值的影响记录下来,从大到小排序,每次改变最大的就行
#include <bits/stdc++.h>
using namespace std ;
using ll = long long ;
int main() {
std::ios::sync_with_stdio(false) ;
std::cin.tie(0) ;
int T ;
cin >> T ;
while (T --) {
int n ;
cin >> n ;
string s ;
cin >> s ;
ll tot = 0 ;
vector<ll> v ;
for (int i = 0 ; i < n ; i ++) {
if (s[i] == 'L') {
v.push_back((n - i - 1) - i) ; //记录改变方向对于总价值的影响
tot += i ;
} else {
v.push_back(i - (n - i - 1)) ;
tot += n - i - 1 ;
}
}
sort(v.begin(), v.end(), greater<int>()) ; //排序
for (int i = 0 ; i < n ; i ++) { //每次改变最大的
if (v[i] > 0) {
tot += v[i] ;
}
cout << tot << ' ' ;
}
cout << '\n' ;
// puts("") ;
}
return 0 ;
}
E-Counting Rectangles
https://codeforces.com/contest/1722/problem/E
首先给你拥有的矩形块,然后每次询问给你另外两个矩形块S,B。要求你求出能够满足:你拥有的矩形块包含A,同时B包含你的拥有的矩形块的所有面积。
可以通过二维前缀和来解决,把所有矩形都以(1,1)为起点,用pre[][]来代表(i , j)包含了从(1,1)到(i,j)的所有矩形块的面积值,同时题目还提到如果长宽都相等,不认为其具有包含或被包含关系
#include <bits/stdc++.h>
using namespace std ;
const int N = 1008 ;
using ll = long long ;
ll num[N][N] ;
ll pre[N][N] ;
int main() {
std::ios::sync_with_stdio(false) ;
std::cin.tie(0) ;
int T ;
cin >> T ;
while (T --) {
ll n, q ;
cin >> n >> q ;
for (int i = 0 ; i <= 1001 ; i ++) {
for (int j = 0 ; j <= 1001 ; j ++) {
num[i][j] = pre[i][j] = 0 ; //初始化
}
}
for (int i = 0 ; i < n ; i ++) {
ll h, w ;
cin >> h >> w ;
num[h][w] += h * w ; //num来记录面积价值
}
for (int i = 1 ; i <= 1000 ; i ++) {
for (int j = 1 ; j <= 1000 ; j ++) {
pre[i][j] = pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1] + num[i][j] ; //构造前缀和
}
}
while (q --) {
ll hs, ws, hb, wb ;
cin >> hs >> ws >> hb >> wb ;
cout << pre[hb - 1][wb - 1] - pre[hb - 1][ws] - pre[hs][wb - 1] + pre[hs][ws] << '\n' ; //因为题目的加粗条件,所以这里是[hb-1][wb-1]和[hs][ws]
}
}
return 0 ;
}
F-L-shapes
https://codeforces.com/contest/1722/problem/F
题目问是否有满足题意的“L”形块,要求不能相邻
首先我们以"L"的拐点作为切入点,遍历图找*点,然后找它的水平和竖直方向是否也存在*点。如果存在且水平和竖直方向上的*点数量都是1,那么我们就认为它是一个“L”。相反,如果水平和竖直方向上的*点数量不等于1,那么我们可以直接输出“NO”。对于每一个已经找到的L,我们把L的三个点都给打上同一个标记。
之后我们再一次遍历图,如果找到了*点,但是这个*点并没有被标记,我们也可以直接输出"NO"。然后对于每一个找到的*点,并且已经被标记了的,我们去找周围是不是有相邻的L,如果有直接输出"NO"。最后我们输出"YES"
#include <bits/stdc++.h>
using namespace std ;
using ll = long long ;
const int N = 1008 ;
const int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1};
const int dy[8] = {1, -1, 0, 0, 1, -1, 1, -1} ;
void solve() {
int n, m ;
cin >> n >> m ;
char g[n][m] ;
int id[n][m] ;
for (int i = 0 ; i < n ; i ++) {
for (int j = 0 ; j < m ; j ++) {
cin >> g[i][j] ;
id[i][j] = 0 ;
}
}
int curr = 1; //标记
for (int i = 0 ; i < n ; i ++) {
for (int j = 0 ; j < m ; j ++) {
if (g[i][j] == '*') {
vector<pair<int, int>> adjh, adjv ; //竖直和水平方向上是否存在*点
if (i > 0 && g[i - 1][j] == '*') {
adjh.emplace_back(i - 1, j) ;
}
if (i < n - 1 && g[i + 1][j] == '*') {
adjh.emplace_back(i + 1, j) ;
}
if (j > 0 && g[i][j - 1] == '*') {
adjv.emplace_back(i, j - 1) ;
}
if (j < m - 1 && g[i][j + 1] == '*') {
adjv.emplace_back(i, j + 1) ;
}
if (adjh.size() == 1 && adjv.size() == 1) { //如果都为1,就打上标记
if (id[i][j] == 0)
id[i][j] = curr ;
else {
cout << "NO" << '\n' ;
return ;
}
if (id[adjh[0].first][adjh[0].second] == 0) {
id[adjh[0].first][adjh[0].second] = curr ;
} else {
cout << "NO" << '\n' ;
return ;
}
if (id[adjv[0].first][adjv[0].second] == 0) {
id[adjv[0].first][adjv[0].second] = curr ;
} else {
cout << "NO" << '\n' ;
return ;
}
curr ++ ;
} else if (adjh.size() > 1 || adjv.size() > 1) {
cout << "NO" << '\n' ;
return ;
}
}
}
}
auto judge = [&](int x, int y) {
if (x >= 0 && x < n && y >= 0 && y < m)
return true ;
else
return false ;
} ;
for (int i = 0 ; i < n ; i ++) {
for (int j = 0 ; j < m ; j ++) {
if (g[i][j] == '*') {
if (id[i][j] == 0) {
cout << "NO" << '\n' ;
return ;
} else { //判断有没有相邻的
for (int it = 0 ; it < 8 ; it ++) {
int tx = i + dx[it] ;
int ty = j + dy[it] ;
if (judge(tx, ty) && id[tx][ty] != id[i][j] && id[tx][ty] != 0) {
cout << "NO" << '\n' ;
return ;
}
}
}
}
}
}
cout << "YES" << '\n' ;
}
int main() {
std::ios::sync_with_stdio(false) ;
std::cin.tie(0) ;
int T ;
cin >> T ;
while (T --) {
solve() ;
}
return 0 ;
}
G-Even-Odd XOR
https://codeforces.com/contest/1722/problem/G
要求你给出n个不同的数组成的序列,里面的偶数下标异或起来等于奇数下标异或起来的值。通过观察我们可以发现,这n个数异或起来的值都是0.那么我们要组成一个n个数都异或起来等于0的值。同时有定理:设a为{1,...,n}的子集,b为a的补集,那么a中元素异或和等于b中元素异或和
所以我们可以考虑先构造前n-2项
#include <bits/stdc++.h>
using namespace std ;
using ll = long long ;
const int N = 1008 ;
void solve() {
int n ;
cin >> n ;
int case1 = 0, case2 = 0 ;
for (int i = 0 ; i < n - 2 ; i ++) {
case1 ^= i ;
case2 ^= i + 1 ;
}
ll addlast = ((ll)1 << 31) - 1 ; //三十个1
if (case1 != 0) {
for (int i = 0 ; i < n - 2 ; i ++) {
cout << i << ' ' ;
}
case1 ^= addlast ;
cout << addlast << ' ' << case1 << '\n' ;
} else {
for (int i = 1 ; i <= n - 2 ; i ++) {
cout << i << ' ' ;
}
case2 ^= addlast ;
cout << addlast << ' ' << case2 << '\n' ;
}
}
int main() {
std::ios::sync_with_stdio(false) ;
std::cin.tie(0) ;
int T ;
cin >> T ;
while (T --) {
solve() ;
}
return 0 ;
}
水平有限 欢迎指正