首页 > 其他分享 >26号个人赛

26号个人赛

时间:2023-07-26 21:11:40浏览次数:33  
标签:26 int long bfs num 个人赛 && 1e9

个人赛链接: https://www.luogu.com.cn/contest/120853#description



A.拯救oibh总部

解题思路

这题很第十四届蓝桥杯的D题有些相似, 我们可以从图的边界外开始入手去遍历整个图来得到答案;

神秘代码1

#include<bits/stdc++.h>
//#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 500 + 10, mod = 1e9 + 7;
int n, m, k, sum, maxn;
char g[N][N];
bool st[N][N];
int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 };
void bfs(int x,int y) {
	st[x][y] = true;
	for (int i = 0; i < 4; i++) {
		int a = x + dx[i], b = y + dy[i];
		if (a >= 0 && a <= n+1 && b >= 0 && b <= m+1 && g[a][b] != '*'&&!st[a][b]) {
			if (g[a][b] == '0') sum--;
			bfs(a, b);
		}
	}
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> g[i][j];
			if (g[i][j] == '0') sum++;
		}
	}
	bfs(0,0);
	cout << sum;
	return 0;
}




C.跳跃机器人

解题思路

这个题我第一眼看起来以为是dfs, 在经历了n次爆栈后还是默默地用bfs过了...

神秘代码

#include<bits/stdc++.h>
//#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 1e7 + 10, mod = 1e9 + 7;
int n, m, k, minn = 1e9;
bool st[N];
int d[N];
int g[4];
int bfs() {
	memset(d, -1, sizeof d);
	queue<int> q;
	q.push(1);
	d[1] = 0;
	while (q.size()) {
		int u = q.front();
		q.pop();
		g[1] = u * 2, g[2] = u + 1, g[3] = u - 1;
		for (int i = 1; i <= 3; i++) {
			int a = g[i];
			if (d[a] == -1&&a<=n) {
				d[a] = d[u] + 1;
				q.push(a);
			}
		}
	}
	return d[n];
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n;
	cout << bfs();
	return 0;
}




D.The Loathesome Hay Baler S

解题思路

因为题目中指明一个齿轮不会由两个齿轮带动, 所以我们在bfs过程中遍历所有齿轮找到所有它能够到的齿轮, 只要这个齿轮还未被其他齿轮带动就可以入队; 本题的一个难点在于寻找传动序列, 这里其实是用了一个邻接表在储存的, 遍历的时候只需要从工作齿轮开始倒着遍历即可;
本题的bfs和常规模板不同, 可以认识认识;

神秘代码

/#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 1100 + 10, mod = 1e9 + 7;
int n, ini, ed;
int xt, yt;
double v[N];
bool st[N];
int mp[N];
struct str {
	int x, y, r;
}wh[N];
void bfs() {
	queue<int> q;
	q.push(ini);
	v[ini] = 10000;
	st[ini] = true;
	while (q.size()) {
		auto t = q.front();
		q.pop();
		for (int i = 1; i <= n; i++) {
			if ((wh[i].x - wh[t].x) * (wh[i].x - wh[t].x) + (wh[i].y - wh[t].y) * (wh[i].y - wh[t].y) == (wh[i].r + wh[t].r) * (wh[i].r + wh[t].r)&&!st[i]) {
				st[i] = true;
				v[i] = v[t] * 1.0 * wh[t].r / wh[i].r;
				mp[i] = t;
				if (i == ed) return;
				q.push(i);
			}
		}
	}
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout .tie(0);
	cin >> n >> xt >> yt;
	for (int i = 1; i <= n; i++) {
		int x, y, r;
		cin >> x >> y >> r;
		wh[i] = { x,y,r };
		if (x == 0 && y == 0) ini = i;
		else if (x == xt && y == yt) ed = i;
	}
	bfs();
	double num =0;
	for (int i = ed; i; i = mp[i]) num+=v[i];
	cout << (int)num;
	return 0;
}




E.电话号码

解题思路

签到题, 哈希和模拟;

神秘代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5 + 10, mod = 1e9 + 7;
int n, m, k, minn = 1e9;
map<char, int> mp;
map<string, int> res;
void ini() {
	int b = 1;
	int d = 0;
	for (int i = 0; i < 26; i++) {
		char c = 'A' + i;
		if (c == 'Q' || c == 'Z')continue;
		d++;
		if (d > 3) d = 1, b++;
		mp[c] = b;
	}
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n;
	ini();
	while (n--) {
		string s;
		cin >> s;
		string s2 = "";
		for (int i = 0; i < s.size(); i++) {
			if (s[i] >= '0' && s[i] <= '9') {
				s2 += s[i];
				if (s2.size() == 3) s2 += '-';
			}
			else if (s[i] >= 'A' && s[i] <= 'Z') {
				char a = '1' + mp[s[i]];
				s2 += a;
				if (s2.size() == 3) s2 += '-';
			}

		}
		res[s2]++;
	}
	bool f = false;
	for (auto t : res) {
		if (t.second > 1) {
			cout << t.first << ' ' << t.second << endl;
			f = true;
		}
	}
	if (!f) cout << "No duplicates." << endl;
	return 0;
}




F.Binary Land

解题思路

本题和后面的I题是本次训练赛最折磨我的两道题, 但是这两道题题型有些相似, 在我搞懂I后, F题也很快就看明白了; 与以往的bfs类型不同, 这两道题就是用了结构体来表示更加复杂的状态, 这也提醒了我bfs的队列中存的是状态, 一直以来自己都说不明白这点...
一开始我因为固有思想也是开了两个数组来分别表示两个企鹅到每个点的步数, 开了两个队列来存位置等等, 反正是越看越迷糊; 然后在看到题解的结构体后真的是非常痛苦... 开一个结构体str表示当前状态, 因素就是当前两只企鹅各自的位置以及走了多少步; 因为bfs的特性, 当时第一次两只企鹅都到达终点时, 此时的步数即为最小步数; 接下来就是正常的bfs路子, 遍历方向, 检查边界; 然后我们需要注意到样例给我们展示的撞墙操作, 企鹅可以往墙壁方向行动, 效果是原地不动, 所以我们更新后得到最后真正的坐标, 然后我们再去判断是否遇到蜘蛛网以及检查当前状态是否已经被标记过了(这里我们开了一个四维数组来存放坐标), 检查结束后, 符合要求的步数加一, 进入队列即可;

神秘代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 30 + 10, mod = 1e9 + 7;
int n, m, num;
int m1, m2, g1, g2, x, y;
char g[N][N];
bool st[N][N][N][N];
int minn=1e9;
int dx[4] = { 1,0,-1,0 }, dyg[4] = { 0,1,0,-1 }, dym[4] = { 0,-1,0,1 };
struct str {
	int x1, y1, x2, y2;
	int step;
};
int bfs() {
	queue<str> q;
	str ini = { m1, m2, g1, g2 ,0};
	q.push(ini);
	while (q.size()) {
		auto t = q.front();
		q.pop();
		if (g[t.x1][t.y1] == 'T' && g[t.x2][t.y2] == 'T') {
			return t.step;
		}
		for (int i = 0; i < 4; i++) {
			int a = t.x1 + dx[i], b = t.y1 + dym[i], c = t.x2 + dx[i], d = t.y2 + dyg[i], s = t.step+1;
			if (a >= 1 && a <= n && b >= 1 && b <= m && c >= 1 && c <= n && d >= 1 && d <= m) {
				if (g[a][b] == '#') a = t.x1, b = t.y1;
				if (g[c][d] == '#') c = t.x2, d = t.y2;
				if (st[a][b][c][d]|| g[a][b] == 'X' || g[c][d] == 'X') continue;
				else {
					str cre = { a,b,c,d,s};
					st[a][b][c][d] = true;
					q.push(cre);
				}
			}
		}
	}
	return -1;
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> g[i][j];
			if (g[i][j] == 'M') m1 = i, m2 = j;
			else if (g[i][j] == 'G') g1 = i, g2 = j;
			else if (g[i][j] == 'T') x = i, y = j;
		}
	}
	int res = bfs();
	if (res == -1) cout << "no" << endl;
	else cout << res;
	return 0;
}




G.The Rock Game S

解题思路

读完题后根据n的范围很容易把二进制和题目联想到一起, 二进制表示当前游戏状态, 0表示没有石头, 1表示有石头; dfs对当前的状态进行遍历, 这里要注意dfs中u和num的定义, 我在这被坑了一下, 当时没多想就写的dfs(0,0), 认为第一个0是当前的状态, 第二个0是当前第几步, 答案要求输出0~2^n步; 但是, 在dfs函数里我们发现, a才是当前的状态, u是上一步的状态, 而num也是上一步是第几步; 所以dfs的截止条件是num = (2^n)-1, 而不是2^n; 理解这一点后我再来说说dfs函数, 我们遍历上一步的状态u的每一位, 如果有石头我们就搬走, 没有就放; 因为每个状态就不能重复, 所以还需要map用来标记; 用数组d来储存所有状态即可;

神秘代码

##include<bits/stdc++.h>
//#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 1e6 + 10, mod = 1e9 + 7;
int n, m, k, idx = 1;
bool st[N];
int d[N];
map<int, int> mp;
vector<int> v;
bool f = false;
void show() {
	for (int i = 0; i <= k; i++) {
		int a = d[i];
		for (int j = 0; j < n; j++) {
			if (a >> j & 1) printf("X");
			else printf("O");
		}
		printf("\n");
	}
}
void dfs(int u, int num) {
	if (f) return;
	if (num == k-1) {
		if (d[k] == 0) {
			show();
			f = true;
		}
		return;
	}
	for (int i = 0; i < n; i++) {
		int a;
		if (u >> i & 1) a = u - (1 << i);
		else a = u + (1 << i);
		if (!mp[a]) {
			mp[a]=1;
			d[num+1] = a;
			dfs(a, num + 1);
			mp[a]=0;
		}
	}
	
}
signed main() {
	scanf("%d", &n);
	k = 1 << n;
	dfs(0, 0);
	return 0;
}




解题思路

这个题真的很怪, 当我打算推导一下w对各个环节的影响时, 我发现题目给的代码已经给我写好了, 于是我糊里糊涂套上之后直接过了, 只能说是...针不戳;

神秘代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 3e6 + 10, mod = 1e9 + 7;
int n, m, k, minn = 1e9;
bool st[N];
int q[N];
void dfs(int l, int r, int num) {
	if (l == r) {
		minn = min(minn, num);
		return;
	}
	for (int w = 0; w <= 1; w++) {
		int mid = l + r + w >> 1;
		if (q[mid] - w < k) {
			dfs(mid + !w, r, num + 1);
		}
		else dfs(l, mid - w, num + 1);
	}
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> q[i];
	cin >> m;
	for (int i = 1; i <= m; i++) {
		cin >> k;
		minn = 1e9;
		dfs(1, n, 0);
		cout << minn << endl;
	}
	return 0;
}




I.Obstacle Course S

解题思路

我又爱又恨的一道题, 真有种打魂类游戏的感觉; 在前面的F题说过了, 用结构体表示状态, 因素有坐标, 方向d(我们用方向数组的下标表示方向, 起点没有方向就设为-1), 以及起点到这个坐标并且朝d方向时所经过的最少转折点num; 这个num就是本题最大的坑点, 也是折磨了我两个小时的地方, 这个等会用到的时候再说; 数组f[i][j]表示起点到(i,j)这个点所经历的最少转折点, 因为要求最小值所以初始化为无穷大; 注意f和num的区别, f没有细分方向, 是这个点的各个方向的num中的最小值;
然后就是bfs起手三件套, 起点初始化, 遍历方向, 检查边界和题目要求; 然后就来到了本题的重点, 根据方向分情况讨论,设上个点为a, 当前点为b, 如果a是起点或者a和b的方向相同, 那么此时b点状态中的num就等于a点状态中的num; 如果方向不同, 那么b的num就是a的num+1; 那么我们该如何判断是否入队呢, 还记得f[i][j]吗, 既然f是当前这个点的最优情况, 那么我们就把b的num和f进行比较, 如果num小于等于f, 那么说明沿着当前这个方向走可能会比f当前的那个方向要好, 所以我们就可以将其入队了; 如果已经到达终点, 就不用将其入队;
这个题给我提供了bfs的一种新的思路和想法, 所以这个题一定要好好看看;

神秘代码

#include<bits/stdc++.h>
//#define int long long
using namespace std;
typedef pair<pair<int, int>, int> PPI;
const int N = 100 + 10, mod = 1e9 + 7;
int n, m, num;
int x, y, x2, y2;
char g[N][N];
int f[N][N];
int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 };
struct str {
	int x, y, d, num;
};
int bfs() {
	memset(f, 0x3f, sizeof f);
	queue<str> q;
	str ini = { x,y,-1,0 };
	q.push(ini);
	f[x][y] = 0;
	while (q.size()) {
		auto t = q.front();
		q.pop();
		int t1 = t.x, t2 = t.y, d = t.d, num = t.num;
		if (t1 == x2 && t2 == y2) continue;
		for (int i = 0; i < 4; i++) {
			int a = t1 + dx[i], b = t2 + dy[i];
			if (a >= 1 && a <= n && b >= 1 && b <= n && g[a][b] != 'x') {
				str cre;
				cre.x = a, cre.y = b, cre.d = i;
				if (d == -1 || i == d) {
					if (f[a][b] >= num) {
						f[a][b] = num;
						cre.num = num;
						q.push(cre);
					}
				}
				else {
					if (f[a][b] >= num + 1) {
						f[a][b] = num + 1;
						cre.num = num +1;
						q.push(cre);
                    }			
				}
			}
		}
	}
	if (f[x2][y2] == 0x3f3f3f3f) return -1;
	else return f[x2][y2];
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			cin >> g[i][j];
			if (g[i][j] == 'A') x = i, y = j;
			else if (g[i][j] == 'B') x2 = i, y2 = j;
		}
	}
	cout << bfs();
	return 0;
}

标签:26,int,long,bfs,num,个人赛,&&,1e9
From: https://www.cnblogs.com/mostimali/p/17583549.html

相关文章

  • 2023.7.26 周三:instanceof
    1/*2instancof判断两个类之间是否有继承关系3Object->String4Object->Person->Teacher5Object->Person->Student6*/7Objects1=newStudent();8System.out.println(s1instanceofObject);//True9System.out.println(s1instanceofPerson);//T......
  • 2023年7月26日 天气:晴
        今天早上起来背了10个英语单词,然后学习了一个小时的java,写了一会英语阅读,然后和朋友出去打了两个小时的羽毛球,最后写了一会作业。    明天打算看一小时的电视剧,然后和朋友出去玩一会,打一两个小时的篮球,最后晚上练一小时的字,然后学习一小时的java。......
  • 7.26日
    一辆车,相约几位朋友,背上几个行囊,趁着青春正好,乘风而来,踏云而去。即刻出发吧,逃离城市的喧嚣,去远方,看见多种生活方式,在闹市里奔忙,在熙攘里踌躇,闻闻草原的芳香,遥望天边的星河。在岁月的时光中,行旅在不曾失语的人间烟火,遥岑于石刻寥若的千年印记。即刻出发吧,到很远的地方去吹风,寻觅......
  • 7.26
    Java数据结构Java工具包提供了强大的数据结构。在Java中的数据结构主要包括以下几种接口和类:枚举(Enumeration)位集合(BitSet)向量(Vector)栈(Stack)字典(Dictionary)哈希表(Hashtable)属性(Properties)枚举(Enumeration)接口虽然它本身不属于数据结构,但它在其他数据结构的范畴里应用......
  • 7.26 后记
    T1不用估价,被骗了正常bfs即可T2会爆__int128,不用记\(a+kb\)的和,一点一点减T3T4匈牙利邻接矩阵\({C_{i,j}}^k\)为\(i\rightarrowj\)恰好经过\(k\)条边的最短路\[C_{i,j}=\sum_{l_1,l_2\dotsl_k}a_{i,l_1}a_{i,l_2}a_{l_{k-1},j}\]园方数P5025CF555E......
  • 行业追踪,2023-07-26,如果主力不骗人,化工原料和磷化工有第一波机会
    自动复盘2023-07-26凡所有相,皆是虚妄。若见诸相非相,即见如来。k线图是最好的老师,每天持续发布板块的rps排名,追踪板块,板块来开仓,板块去清仓,丢弃自以为是的想法,板块去留让市场来告诉你跟踪板块总结:成交额超过100亿排名靠前,macd柱由绿转红成交量要大于均线有必要给每个行......
  • 暑假集训D3 2023.7.26 补题
    G.P6183[USACO10MAR]TheRockGameS题意:给定长度n,构造\(2^n\)个由X和O组成的字符串,使得第一个字符串和最后一个字符串只由O组成,并且相邻的字符串只有一处不同,不得有重复的字符串.BFS貌似做不了.看题解有佬用格雷码的知识.代码如下#include<stdio.h>#include<st......
  • 7/26
    问题B:最优乘车#include<bits/stdc++.h>usingnamespacestd;intm,n,vis[501];vector<int>g[501];intst;voidbfs(){queue<int>q;while(!q.empty())q.pop();q.push(1);vis[1]=0;while(!q.empty()){inth=q.front()......
  • 20230726
    复赛完全背包定义:有n种物品和一个容量为v的背包,第i种物品体积为c[i],价值为w[i],每种物品有无穷件,问如何选取物品放入背包,可使价值总和最大。与01背包的区别:01背包一个物品只能选一件,而完全背包一个物品可以选多件例题时间:1s空间:128M题目描述:一个旅行者有一个最......
  • 2023-7-26 Dynamic替代部分反射的简单实现方式
    Dynamic与反射的使用【作者】长生实体类publicclassSchool{ publicintGetAge(){ return100;}}使用反射获取对象里的方法 Schoolschool=newSchool(); varmethod=typeof(School).GetMethod("GetAge"); intage=(int)method.Invoke(school,null); Console.W......