目录
Problem - A - Codeforces
1.1翻译
InputCopy
7
100
1010
101
105
2033
1019
1002
OutputCopy
NO
YES
NO
YES
NO
YES
NO
1.2思路
因为输入的数只能是4位,根据题意可知前两位必定是10,而后两位则是3~99的数字,所以重要的数只能在103到1099这个区间,这样我们就可以直接打表来做
1.3代码
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<cmath>
#include<set>
#include<stack>
#include<unordered_map>
using namespace std;
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define mm(a, b) memset(a, b, sizeof(a))
#define ll long long
#define mp make_pair
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f, mod = 1e9 + 7;
const int N = 1e5 + 10, P = 13331, len = 5e3 + 10;
void solve() {//用set方便查找
set<int>p = { 102,103, 104, 105, 106, 107, 108, 109,
1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019,
1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029,
1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039,
1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049,
1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059,
1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069,
1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079,
1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089,
1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099 };
int n; cin >> n;
for (int i = 0; i < n; i++) {
int x; cin >> x;
if (p.find(x) != p.end())cout << "YES\n";
else cout << "NO\n";
}
}
int main() {
ios;
int t;
t = 1;
while (t--) solve();
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------
Problem - B - Codeforces
2.1翻译
InputCopy
4
5
5 4 2 1 3
3
2 3 1
4
2 3 1 4
5
1 2 3 5 4
OutputCopy
NO
YES
YES
NO
2.2思路
就是按照题目模拟,看是不是所有人都遵守规则即可。
2.3代码
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<cmath>
#include<set>
#include<stack>
#include<unordered_set>
using namespace std;
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define mm(a, b) memset(a, b, sizeof(a))
#define ll long long
#define mp make_pair
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f, mod = 1e9 + 7;
const int N = 1e5 + 10, P = 13331, len = 5e3 + 10;
void solve() {
int n; cin >> n;
vector<int>a(n);
for (int i = 0; i < n; i++)cin >> a[i];
unordered_set<int> p;
bool vis = true;
for (int i = 0; i < n; ++i) {
int seat = a[i];
if (i == 0) {
p.insert(seat);
}
else {
if (p.count(seat - 1) || p.count(seat + 1)) {
p.insert(seat);
}
else {
vis = false;
break;
}
}
}
if (vis) {
cout << "YES" << "\n";
}
else {
cout << "NO" << "\n";
}
}
int main() {
ios;
int t;
cin >> t;
while (t--) solve();
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------
Problem - C - Codeforces
3.1翻译
InputCopy
3
5
3 5 2 1 3
2
abfda
afbfa
2
1 2
3
ab
abc
aa
4
5 -3 5 -3
4
aaaa
bcbc
aba
cbcb
OutputCopy
YES
NO
YES
NO
NO
NO
YES
NO
YES
3.2思路
题意就是给出一组数和一个字符串,他俩长度得相同,a中每个数字只对应s中的一个字符,就是相同的,所以只需要用unordered_map记录数字对应字符,字符对应数字,最后看是否匹配即可;
这轮结束后,发现好像只用map<string,vector<int>>也可以,就判断vector数组的大小是不是1就可以,不用两个unordered_map对照。
3.3代码
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<cmath>
#include<set>
#include<stack>
#include<unordered_map>
using namespace std;
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define mm(a, b) memset(a, b, sizeof(a))
#define ll long long
#define mp make_pair
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f, mod = 1e9 + 7;
const int N = 1e5 + 10, P = 13331, len = 5e3 + 10;
void solve() {
int n; cin >> n;
vector<int> a(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
int m; cin >> m;
vector<string> s(m);
for (int i = 0; i < m; ++i) cin >> s[i];
for (int i = 0; i < m; ++i) {
if (s[i].size() != n) {
cout << "NO" << endl;
continue;
}
unordered_map<int, char> nc;
unordered_map<char, int> cn;
bool match = true;
for (int j = 0; j < n; ++j) {
if (nc.find(a[j]) == nc.end() && cn.find(s[i][j]) == cn.end()) {
nc[a[j]] = s[i][j];
cn[s[i][j]] = a[j];
}
else {
if (nc[a[j]] != s[i][j] || cn[s[i][j]] != a[j]) {
match = false;
break;
}
}
}
if (match) {
cout << "YES" << endl;
}
else {
cout << "NO" << endl;
}
}
}
int main() {
ios;
int t;
cin >> t;
while (t--) solve();
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------
Problem - D - Codeforces
4.1翻译
InputCopy
4
6
3 5 1 4 3 2
LRLLLR
2
2 8
LR
2
3 9
RL
5
1 2 3 4 5
LRLRR
OutputCopy
18
10
0
22
4.2思路
题目告诉我们要计算从L到R的子区间和,要求相加最大,每次使用的LR都会被标记不能使用;
我们可以用前缀和记录每个区间的值,再贪心地每次都让区间距离尽可能大,从左端点到右端点
例如样例4,我们可以先取第一个L和最后一个R,再取第二个L和倒数最后二个R;
就可以用双指针从左端点和右端点开始历遍。
4.3代码
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<cmath>
#include<set>
#include<stack>
#include<unordered_map>
using namespace std;
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define mm(a, b) memset(a, b, sizeof(a))
#define ll long long
#define mp make_pair
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f, mod = 1e9 + 7;
const int N = 2e5 + 10, P = 13331, len = 5e3 + 10;
void solve() {
int n;
cin >> n;
vector<int> a(n);
vector<ll> s(n + 1, 0);//前缀和
for (int i = 0; i < n; i++) {
cin >> a[i];
s[i + 1] = s[i] + a[i];
}
string c;
cin >> c;
ll ans = 0;
int l = 0, r = n - 1;//左指针,右指针
while (l < r) {//循环退出条件
while (l < r && c[l] != 'L') l++;//从左开始搜,搜到’L‘退出循环记录下标
while (l < r && c[r] != 'R') r--;//从右开始搜,搜到’R‘退出循环记录下标
if (l < r) {
ans += s[r + 1] - s[l];//累加值
l++;//路程+1防止重复
r--;
}
}
cout << ans << endl;
}
int main() {
ios;
int t;
cin >> t;
while (t--) solve();
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------
Problem - E - Codeforces
5.1翻译
InputCopy
5
3 4 2
9
1 1 1 1 1 1 1 1 1
2 1 1
2
5 7
20 15 7
9
4 1 4 5 6 1 1000000000 898 777
1984 1 1
4
5 4 1499 2004
9 5 5
6
6 7 14 16 16 6
OutputCopy
21
12
49000083104
3512
319
5.2思路
给你一个二维平面方格,让你求每个长度为k的子方格的值之和,类似于牛客卷积平面那道题;
依旧以贪心思想为核心,优先队列辅助记录;
由样例解释可以看到,中心的格子会被多次记录,所以我们只需要把大值从中心向外填充即可,因为用二维平面填充比较困难,所以我们就可以转化为记录每个格子被重复记录的个数,用优先队列将其储存,每次取队头与最高的猩猩乘积得值最后相加就可以了。
5.3代码
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<cmath>
#include<set>
#include<stack>
#include<unordered_map>
using namespace std;
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define mm(a, b) memset(a, b, sizeof(a))
#define ll long long
#define mp make_pair
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int inf = 0x3f3f3f3f, mod = 1e9 + 7;
const int N = 2e5 + 10, P = 13331, len = 5e3 + 10;
int main() {
int t;
cin >> t;
while (t--) {
int n, m, k, w;
cin >> n >> m >> k >> w;
vector<int> a(w);
for (int i = 0; i < w; i++) {
cin >> a[i];
}
sort(a.rbegin(), a.rend());//由大到小
vector<vector<int>> grid(n, vector<int>(m, 0));
//遍历每个方格在每个子方格中出现次数,出现多的就存大值
for (int i = 0; i <= n - k; i++) {
for (int j = 0; j <= m - k; j++) {
for (int x = i; x < i + k; x++) {
for (int y = j; y < j + k; y++) {
grid[x][y]++;
}
}
}
}
//优先队列将每个格子储存并排序
priority_queue<int> pq;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] > 0) {
pq.push(grid[i][j]);
}
}
}
ll res = 0;
for (int i = 0; i < w && !pq.empty(); i++) {
int top = pq.top();//取队头最大值,即单个格子被使用次数最多的;
pq.pop();//删除
res += static_cast<ll>(top) * a[i];//用最高的猩猩与队头×得到一个最大值
}
cout << res << "\n";
}
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------