文章目录
A. Spell Check
题目大意
给定一个字符串并检测是否是原字符串的有效拼写。
思路
首先给定字符串长度要是五,然后统计出现的字符是不是都在原字符串中就可以了。具体看代码。
AC代码
#include<iostream>
#include<map>
using namespace std;
int main() {
int t; cin >> t;
while (t--) {
int n; cin >> n;
map<char, int> mp;
string s; cin >> s;
if (n > 5 || n < 5) {
cout << "NO" << endl;
continue;
}
for (int i = 0; i < s.length(); i++) {
mp[s[i]]++;
}
int tmp = 0;
for (auto it : mp) {
if(it.second==1)
if (it.first == 'T' || it.first == 'i' ||
it.first == 'm' || it.first == 'u' ||
it.first == 'r')
tmp++;
}
if (tmp == 5)cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
B. Colourblindness
题目大意
有两行字符串,字符串中的字符代表颜色,这个人会将蓝色和绿色看成一个颜色,判断两个字符串是否在他眼里相同。
思路
就用字符1,2来表示每个字符,红色表示为1,蓝色和绿色表示为2,最后直接比较修改后的两个字符串是否相等就好了。
AC代码
#include<iostream>
using namespace std;
char tu[5][105];
int main() {
int t; cin >> t;
while (t--) {
int n; cin >> n;
for (int i = 1; i <= 2; i++) {
for (int j = 1; j <= n; j++) {
char ch; cin >> ch;
if(ch=='R')
tu[i][j] = '1';
if (ch == 'G' || ch == 'B')
tu[i][j] = '2';
}
}
int f = 0;
for (int i = 1; i <= n; i++) {
if (tu[1][i] != tu[2][i]) {
f = 1;
break;
}
}
if (f == 1)cout << "NO" << endl;
else cout << "YES" << endl;
}
}
C. Word Game
题目大意
有三个人每个人写下n
最终求每个人的得分
思路
枚举每个人,和当前的人所写的字符串,与其他两个人所写的字符串比较,并记录相同的个数。若当前人写的某个字符串,其余两个人都写了,那么当前人不得分,若当前人写的某个字符串,其余两人中一个人写了,那么当前人得1分。没人写得情况同理。
AC代码
#include<iostream>
#include<map>
using namespace std;
const int M = 1005;
string s[M][M];
int ans[5];
int main() {
int t; cin >> t;
while (t--) {
map<string, int> mp[4];
int n; cin >> n;
for (int i = 1; i <= 3; i++) {
ans[i] = 0;
for (int j = 1; j <= n; j++) {
cin >> s[i][j];
mp[i][s[i][j]]++;
}
}
/* for (int i = 1; i <= 3; i++) {
for (auto it : mp[i]) {
cout << it.first << " ";
}
cout << endl;
}*/
for (int i = 1; i <= 3; i++) {
int cnt = 0;
for (int j = 1; j <= n; j++) {
int tmp1 = (i + 1) % 3 == 0 ? 3 : (i + 1) % 3;
int tmp2 = (i + 2) % 3 == 0 ? 3 : (i + 2) % 3;
if (mp[tmp1].count(s[i][j]))
cnt++;
if (mp[tmp2].count(s[i][j]))
cnt++;
if (cnt == 0) ans[i] += 3;
if (cnt == 1) ans[i] += 1;
if (cnt == 2) ans[i] += 0;
cnt = 0;
}
}
for (int i = 1; i <= 3; i++) {
cout << ans[i] << " ";
}
cout << endl;
}
return 0;
}
D. Line
题目大意
在一条水平线上有 n个人,每个人要么向左看,要么向右看。每个人都数着他们所看方向的人数。这条线的值是每个人计数的总和。最多可以改变1~n个人的看的方向,求每一个数量的改变后的值的最大值。
思路
求出每一个位置向左看或是向右看的价值,然后将这些价值升序排序,从n~1逐个选取求和就行了,当然要舍去负价值的可能改变。
AC代码
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int M = 2e5 + 5;
char zi[M];
ll val[M];
int main() {
int t; cin >> t;
while (t--) {
int n; cin >> n;
for (int i = 1; i <= n; i++) {
cin >> zi[i];
val[i] = 0;
}
ll ans = 0;
for (int i = 1; i <= n; i++) {
if (zi[i] == 'L') {
ans += i - 1; //原本的向左看的价值
val[i] = n - 2 * i + 1; //向右看的价值与向左看的价值的差
}
else {
ans += n - i; //原本的向右看的价值
val[i] = 2 * i - 1 - n; //向左看的价值与向右看的价值的差
}
}
sort(val + 1, val + 1 + n);
for (int i = n; i >= 1; i--) {
if (val[i] > 0) ans += val[i];
cout << ans << " ";
}
cout << endl;
}
}
E. Counting Rectangles
题目大意
给定数个矩形的长宽,然后给定q次查询,每次查询输入hs,ws,hb,wb代表在
长宽在这个区间范围内的矩形的面积总和。
思路
本题可以化为一个二维区间前缀和的问题。sum[i][j]就表示,长宽在i,j(包括i,j)之前的所有矩形的面积总和,这样的话求上面规定区间中的面积总和就好求了。
具体见代码
AC代码
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int M = 1e3 + 5;
ll sum[M][M];
int main() {
int t; cin >> t;
while (t--) {
int n, q; cin >> n >> q;
memset(sum, 0, sizeof(sum));
for (int i = 1; i <= n; i++) {
ll h, w; cin >> h >> w;
sum[h][w] += h * w;
}
for (int i = 1; i <= 1000; i++) {
for (int j = 1; j <= 1000; j++) {
sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
}
}
for (int k = 1; k <= q; k++) {
int hs, ws, hb, wb;
cin >> hs >> ws >> hb >> wb;
ll ans = sum[hb - 1][wb - 1] - sum[hb - 1][ws] - sum[hs][wb - 1] + sum[hs][ws];
cout << ans << endl;
}
}
}
F. L-shapes
题目大意
一张网格纸,判断上面的阴影区域是否能且只能构成不相交,也不相接的L字形。
思路
两次广搜,第一次判断是否有且只有由三个连续的阴影块组成的阴影区域。
第二次判断阴影区域的形状是否都是L型。两条都满足,就YES,否则NO。
AC代码
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
char mp[55][55];
int vis[55][55];
int mov[8][2] = { {-1,0},{1,0},{0,-1},{0,1} ,{1,1},{1,-1 },
{-1,1},{-1,-1} };
int n, m;
struct node {
int x, y;
};
bool check(int x, int y) {
return x >= 1 && x <= n && y >= 1 && y <= m;
}
vector<node> v;
void bfs(int x, int y) {
queue<node> q;
v.clear();
q.push({ x,y });
v.push_back({ x,y });
vis[x][y] = 1;
while (!q.empty()) {
node now = q.front();
q.pop();
for (int i = 0; i <8; i++) {
int xx = now.x + mov[i][0];
int yy = now.y + mov[i][1];
if (check(xx, yy) && !vis[xx][yy] && mp[xx][yy] == '*') {
vis[xx][yy] = 1;
v.push_back({ xx,yy });
q.push({ xx,yy });
}
}
}
}
char step[4] = { 'u','d','l','r' };
struct nodel {
int x, y;
string st;
nodel(int a, int b, string c) {
x = a; y = b; st = c;
}
nodel(){}
};
string bfs1(int x, int y) {
// cout << x << " " << y << endl;
string s = "";
queue<nodel> q;
q.push(nodel(x,y,s));
vis[x][y] = 1;
while (!q.empty()) {
nodel p = q.front();
q.pop();
string tmp = p.st;
// cout << tmp << endl;
if (tmp.size() == 2) return tmp;
for (int i = 0; i < 4; i++) {
int xx = p.x + mov[i][0];
int yy = p.y + mov[i][1];
if (check(xx, yy) && !vis[xx][yy] && mp[xx][yy] == '*') {
vis[xx][yy] = 1;
tmp += step[i];
// cout << tmp << endl;
if (tmp.size() == 2) return tmp;
q.push({ xx,yy ,tmp});
}
}
}
return "uu";
}
int main() {
int t; cin >> t;
while (t--) {
cin >> n >> m;
memset(mp, 0, sizeof(mp));
memset (vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> mp[i][j];
}
}
int f = 0;
for (int i = 1; i <= n; i++) {
for (int j =1 ; j <= m; j++) {
if (!vis[i][j]&&mp[i][j]=='*') {
bfs(i, j);
if (v.size() != 3) {
f = 1;
break;
}
}
}
if (f == 1)break;
}
if (f == 1) cout << "NO" << endl;
else {
int che = 0;
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (mp[i][j] == '*' && !vis[i][j]) {
string s=bfs1(i, j);
// cout << s << endl;
if (s == "uu" || s == "ll" || s == "rr" ||
s == "dd") {
che = 1;
break;
}
}
}
if (che == 1) break;
}
if (che == 1) cout << "NO" << endl;
else
cout << "YES" << endl;
}
}
}