ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

蓝桥杯模拟小记

2022-02-26 18:01:35  阅读:174  来源: 互联网

标签:nx dist int 样例 蓝桥 ny include 模拟 小记


image-20220226173345639

【思路】由于完全平方公式\(a^2 - b^2 = (a+b)(a-b)=c\),假设 $ d $ 可以拆分成这样的平方差,\(c + b ^2 = a ^2\)。

假设\(a + b\) 都大于 \(c\) 了,而\(a - b\)又不可能小于1,所以\(a\)和\(b\)不能大于\(c\)。这样我们就可以缩小遍历的范围了。

答案:78

#include <iostream>
#include <cmath>
using namespace std;


int main() {
	int sum = 0;
	for (int i = 1; i <= 2021; i++) {
		for (int j = 0; j <= i; j++) {
			int k = i + j * j;
			int sq = sqrt(k);
			if (sq * sq == k) {
				sum++;
				break;
			}
		}
	}
	cout << sum << endl;
	return 0;
}

问题描述(哈夫曼编码)

image-20220226173950974

【思路】本题考察的是哈夫曼编码,要使得最终编码的长度最少,那么就尽可能地使数量最多的字母长度最短,越靠近树的根节点数值越大,然后每个子分支的边从左到右分别为0和1,从根节点依次数下来就是某个字母对应的编码,再求出所有编码所用的字母数。

答案:219


01最短路问题

问题描述

小蓝住在 LQ 城,今天他要去小乔家玩。
 LQ 城可以看成是一个 n 行 m 列的一个方格图。
 小蓝家住在第 1 行第 1 列,小乔家住在第 n 行第 m 列。
 小蓝可以在方格图内走,他不愿意走到方格图外。
 城市中有的地方是风景优美的公园,有的地方是熙熙攘攘的街道。小蓝很喜欢公园,不喜欢街道。他把方格图中的每一格都标注了一个属性,或者是喜欢的公园,标为1,或者是不喜欢的街道标为2。小蓝和小乔住的地方都标为了1。
 小蓝每次只能从一个方格走到同一行或同一列的相邻方格。他想找到一条路径,使得不连续走两次标为 2 的街道,请问在此前提下他最少要经过几次街道?

输入格式

输入的第一行包含两个整数 n, m,用一个空格分隔。
 接下来 n 行,每行一个长度为 m 第数字串,表示城市的标注。

输出格式

输出一行包含一个整数,表示答案。如果没有满足条件的方案,输出 -1。

样例输入

3 4
1121
1211
2211

样例输出

2

样例输入

3 4
1122
1221
2211

样例输出

-1

样例输入

5 6
112121
122221
221212
211122
111121

样例输出

5

评测用例规模与约定

对于 50% 的评测用例,2 <= n, m <= 20。
 对于所有评测用例,2 <= n, m <= 300。

【思路】题目的意思是走到终点的之前不能连续经过两个\(2\),而且最终要统计经过的\(2\)的个数。

2-->2 inf

2-->1 0

1-->1 0

1-->2 1

可以发现这里面只有0和1两种距离,可以采用双端队列\(BFS\)来写,也可采用深搜剪枝。

\(01BFS\),双端队列做法

include <iostream>
#include <cstring>
#include <deque>
#define x first
#define y second
using namespace std;
using T = pair<int, int>;
const int N = 305, M = N * N;
const int inf = 0x3f3f3f3f;
int res = inf;
int g[N][N];
bool st[N][N];
int  dist[N][N];
int n, m;

int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, 1, -1};
int bfs() {
	memset(dist, 0x3f, sizeof dist);
	deque<T> q;
	q.push_back({0, 0});
	dist[0][0] = 0;

	while (q.size()) {
		auto t = q.front();
		q.pop_front();

		for (int i = 0; i < 4; i++) {
			int nx = t.x + dx[i], ny = t.y + dy[i];
			if (nx < 0 || nx >= n || ny < 0 || ny >= m)
				continue;
			if (g[t.x][t.y] == 2 && g[nx][ny] == 2)
				continue;
			if (g[nx][ny] == 1 && dist[nx][ny] > dist[t.x][t.y])	{
				dist[nx][ny] = dist[t.x][t.y] + 0;
				q.push_front({nx, ny});
				//cout << " 下一个为1" << endl;
			}
			if (g[nx][ny] == 2 && dist[nx][ny] > dist[t.x][t.y] + 1) { // 只有距离变小才能入队
				dist[nx][ny] = dist[t.x][t.y] + 1;
				q.push_back({nx, ny});
				//cout << " 下一个为2" << endl;
			}
		}
	}
	if (dist[n - 1][m - 1] == 0x3f3f3f3f)
		return -1;
	return dist[n - 1][m - 1];
}


int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; i++) {
		string s;
		cin >> s;
		for (int j = 0; j < m; j++)
			g[i][j] = s[j] - '0';
	}
	cout << bfs();
	return 0;
}

\(dfs\)深搜

#include <iostream>
#include <cstring>
#include <deque>
#define x first
#define y second
using namespace std;
using T = pair<int, int>;
const int N = 305, M = N * N;
const int inf = 0x3f3f3f3f;
//int res = inf;
int g[N][N];
bool st[N][N];
int  dist[N][N];
int n, m;

int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, 1, -1};

void dfs(int x, int y, int cnt) { // 经过 2 的个数
	if (x == n - 1 && y == m - 1) {
		res = min(res, cnt);
		return;
	}
	st[x][y] = true;
	// 从x y向四个方向扩展
	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i], ny = y + dy[i];
		if (nx < 0 || nx >= n || ny < 0 || ny >= m)
			continue;
		if (st[nx][ny])
			continue;
		if (g[x][y] == 2 && g[nx][ny] == 2)
			continue; // 不能走连续的2
		dfs(nx, ny, g[nx][ny] == 2 ? cnt + 1 : cnt);
	}
	st[x][y] = false;
}


int main() {
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; i++) {
		string s;
		cin >> s;
		for (int j = 0; j < m; j++)
			g[i][j] = s[j] - '0';
	}
	dfs(0, 0, 0);
	if (res == inf)
		puts("-1");
	else
		cout << res << endl;

	cout << bfs();
	return 0;
}

标签:nx,dist,int,样例,蓝桥,ny,include,模拟,小记
来源: https://www.cnblogs.com/ddja/p/15940012.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有