A - Digit Machine
Code
#include <bits/stdc++.h>
using namespace std;
int n, x, a[10];
int main()
{
while (cin >> x) a[n++] = x;
int t = 0;
for (int i = 1; i <= 3; i++)
{
t = a[t];
}
cout << t;
return 0;
}
B - Pasta
Code
#include <bits/stdc++.h>
using namespace std;
int n, m;
unordered_map<int, int> cnt;
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
cnt[x]++;
}
while (m--)
{
int x;
cin >> x;
if (cnt[x] > 0) cnt[x]--;
else
{
puts("No");
return 0;
}
}
puts("Yes");
}
C - Connect 6
解题思路
1.枚举每个格子构成的6 * 6 网格(注意处理边界问题)
2.只有当横、竖或者两条对角线的黑色方格数>= 4
时,才可以成功(因为最多涂黑两个方格)
方格图对角线元素点击此处查看,加深理解
TIPS:下面代码枚举反对角线时是构某个格子的右上方6 * 6网格
OS:很难想象学了这么久我竟然都不会枚举正、反对角线元素,我是rz
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n;
string g[N];
int main()
{
cin >> n;
for (int i = 0; i < n; i++) cin >> g[i];
bool ans = false;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
if (i + 5 < n)
{
int cnt = 0;
for (int k = 0; k < 6; k++)
if (g[i + k][j] == '#') cnt++;
if (cnt >= 4) ans = true;
}
if (j + 5 < n)
{
int cnt = 0;
for (int k = 0; k < 6; k++)
if (g[i][j + k] == '#') cnt++;
if (cnt >= 4) ans = true;
}
if (i + 5 < n && j + 5 < n)
{
int cnt = 0;
for (int k = 0; k < 6; k++)
if (g[i + k][j + k] == '#') cnt++;
if (cnt >= 4) ans = true;
}
if (i - 5 >= 0 && j + 5 < n)
{
int cnt = 0;
for (int k = 0; k < 6; k++)
if (g[i - k][j + k] == '#') cnt++;
if (cnt >= 4) ans = true;
}
}
if (ans) puts("Yes");
else puts("No");
return 0;
}
D - Sequence Query(Multiset + 二分)
题目描述
我们有一个空序列。
给定Q个查询,按顺序处理它们。
每个查询属于以下三种类型之一。
1 x
:将 x
插入到 A
2 x k
:找到小于等于x
的集合中第k
大的数
3 x k
:找到大于等于x
的集合中第k
小的数
数据范围:
1
≤
Q
≤
2
∗
1
0
5
1 \le Q \le 2 * 10 ^5
1≤Q≤2∗105
1
≤
x
≤
1
0
1
8
1 \le x \le 10 ^18
1≤x≤1018
1
≤
k
≤
5
1 \le k \le 5
1≤k≤5
解题思路
本题用到了multiset
数据结构,可以做到让元素从小到大排序,并且可以重复
然后再结合multiset自带的二分查找(
O
(
l
o
g
n
)
O(logn)
O(logn))给定的元素
分情况:
1. 对于op == 2
的操作, 使用upper_bound找大于元素x的第一个位置,然后往前找,次数为k
2. 对于op == 2
的操作, 使用lower_bound找大于等于元素的第一个位置,然后往后找,由于这个位置已经符合条件,所以次数为k - 1
OS: 比赛的时候没有正确分析复杂度,思路很接近正解,但是没有用二分。 被很多题解被迷惑了,导致补题的时候被卡了两个小时!
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
bool flag;
ll q, op, x, k;
multiset<long long> s;
int main()
{
cin >> q;
while (q--)
{
cin >> op >> x;
if (op == 1) s.insert(x);
else if (op == 2)
{
cin >> k;
auto it = s.upper_bound(x);
flag = true;
for (int i = 1; i <= k; i++) // 每次都移动it指针
{
if (it == s.begin()) flag = false; // 只有当当前元素不是begin(), 才说明前面还有元素
else --it; // 前面还有元素,所以--
}
if (flag) cout << *it << endl;
else puts("-1");
}
else
{
cin >> k;
auto it = s.lower_bound(x);
flag = true;
for (int i = 1; i < k; i++) // 由于找到的这个位置已经符合条件,所以次数为 k - 1
{
if (it == s.end()) flag = false; // 如果到了末尾,就置为false
else ++it; // 只有不是末尾时,才++; 在 i == k时,有可能这一次移动导致移到了end,所以有了下面的特判
}
if (it == s.end()) flag = false; // 特判最后一个元素, 因为可能最后一次移动到了end
if (flag) cout << *it << endl;
else puts("-1");
}
}
return 0;
}
E - Putting Candies
题目描述
解题思路
OS:以后再补吧,没时间咯
详细题解参考此处
F - Skate(BFS)
题目描述
解题思路
经观察可得,只有障碍物的四周能达到
所以我们只需要分别对行、列枚举障碍物的四周
用二分查找到同行同列的元素,并进行判断
如果每次能找到符合条件的元素的话,就在原先的基础上距离 + 1
详细题解参考此处
Code
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N = 100010;
typedef pair<int, int> PII;
int h, w, n, sx, sy, ex, ey;
map<PII,int> vis;
PII row[N], col[N];
struct node
{
int x, y, d;
};
int BFS()
{
queue<node> q;
q.push({sx, sy, 0});
while (q.size())
{
auto t = q.front();
q.pop();
if (vis[{t.x, t.y}]) continue;
vis[{t.x, t.y}] = 1;
if (t.x == ex && t.y == ey) return t.d;
auto it = lower_bound(row + 1, row + n + 1, PII {t.x, t.y}); // 在同行中变换列
int tx = it->x, ty = it->y;
if (t.x == tx && t.y != ty - 1) q.push({tx, ty - 1, t.d + 1});
it--;
tx = it->x, ty = it->y;
if (t.x == tx && t.y != ty + 1) q.push({tx, ty + 1, t.d + 1});
it = lower_bound(col + 1, col + n + 1, PII {t.y, t.x}); // 在同列中变换行
ty = it->x, tx = it->y;
if (t.y == ty && t.x != tx - 1) q.push({tx - 1, ty, t.d + 1});
it--;
ty = it->x, tx = it->y;
if (t.y == ty && t.x != tx + 1) q.push({tx + 1, ty, t.d + 1});
}
return -1;
}
int main()
{
cin >> h >> w >> n;
cin >> sx >> sy >> ex >> ey;
for (int i = 1; i <= n; i++) // 从1读可以保证row,col中有{0,0}以免--it出现边界问题
{
int r, c;
cin >> r >> c;
row[i] = {r, c};
col[i] = {c, r};
}
sort(row + 1, row + 1 + n); sort(col + 1, col + 1 + n);
cout << BFS() << endl;
return 0;
}