文章目录
牛客小白月赛100(思维、模拟、BFS、分块、三元环、并查集)
A. ACM中的A题
根据题意,模拟翻倍即可。
不能只翻倍最短边(eg:2、5、10)。注意数据范围。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main(){
ll a[3];
for(int i = 0; i < 3; i++) cin >> a[i];
int flag = 0;
for(int i = 0; i < 3; i++){
vector<ll> v;
for(int j = 0; j < 3; j++){
v.push_back(i == j ? a[j]*2 : a[j]);
}
sort(v.begin(), v.end());
if(v[0] + v[1] > v[2]) flag = 1;
}
cout << (flag ? "Yes" : "No") << endl;
return 0;
}
B. ACM中的C题
通过简单思考,得到三种情况:
- n =1:res = -1
- n = 2k:两两交换即可
- n = 2k+1 && n > 1:两两交换会剩下最后一个,需要多交换一次
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
if(n == 1) n = -3;
cout << (n+1) / 2 << endl;
return 0;
}
C. ACM中的M题(思维)
B题可以理解为所有数据为一组,C题只需要根据 b 数组对 a 数组进行分组,再分别判断即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5;
map<int, int> v;
int main(){
int n;
cin >> n;
int x;
for(int i = 1; i <= n; i++) cin >> x;
for(int i = 1; i <= n; i++){
cin >> x;
v[x]++;
}
int res = 0;
for(auto item : v){
int val = item.second;
if(val == 1){
res = -1;
break;
}
res += (val + 1) / 2;
}
cout << res << endl;
return 0;
}
D. ACM中的AC题(模拟,BFS)
说一下我的处理方法:
从起点开始BFS,记录对于起点的相对位移(只记录正方向)。
比如,起点为(XS, YS),相对位移为(x, y),则 “我” 的坐标为(XS + x,YS + y),“另一个我”的坐标为(XS - x,YS - y)。
在BFS的过程中,会有三种情况:
- “我” 和 “另一个我” 都没走到传送门
- 只有 “我” 走到了传送门
- 只有 “另一个我” 走到了传送门
使用一个flag,记录三种状态,分别处理即可。
处理一点点细节就好了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e3+5;
int visited[maxn*2][maxn*2][3];
char mp[maxn][maxn];
int idx[5] = {0, 0, 0, 1, -1};
int idy[5] = {0, 1, -1, 0, 0};
typedef struct Node{
int x, y; // 对于起点的相对位移
int flag; // 0:两个人都没进,1:正方向的人进了,2:负方向的人进了
int count; // 走了几步
} node;
queue<node> qu;
void push(node a){ // 进队
if(visited[a.x+2001][a.y+2001][a.flag] == 0){ // 注意相对位移可能有负值,是否已经被BFS到
qu.push(a);
visited[a.x+2001][a.y+2001][a.flag] = 1;
}
}
int main(){
int n, m, x, y;
cin >> n >> m >> x >> y;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> mp[i][j];
}
}
int res = -1;
qu.push({0, 0, 0, 0}); // 枚举距离起点的相对位移
visited[0][0][0] = 1;
while(!qu.empty()){
int xx = qu.front().x;
int yy = qu.front().y;
int flag = qu.front().flag;
int count = qu.front().count + 1; // 要走下一步了
qu.pop();
for(int i = 1; i <= 4; i++){
int x1 = x + xx + idx[i], x2 = x - xx - idx[i]; // 下一步两个人的坐标
int y1 = y + yy + idy[i], y2 = y - yy - idy[i]; // 下一步两个人的坐标
if(flag == 0){ // 都没进
if(x1 < 1 || x1 > n || x2 < 1 || x2 > n) continue;
if(y1 < 1 || y1 > m || y2 < 1 || y2 > m) continue;
if(mp[x1][y1]