【蓝桥杯】2022年第十三届

A 九进制转十进制

思路 简单进制转化
代码
#include <bits/stdc++.h>
using namespace std;

int n = 2022;
int sum = 0;
int t = 0;
int main() {
	while (n > 0) {
		sum += pow(9, t) * (n % 10);
		n /= 10;
		t++;
	}
	cout << sum;
	return 0;
}

B 顺子日期

思路 日期计算,遍历每一个日期并判断
代码
#include <bits/stdc++.h>
using namespace std;

string month[13] = {"0", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"};
int mday[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int ans = 0;
void cheak(string s) {
	int cnt = 1;
	int res = 0;
	for (int i = 0; i < s.size() - 1; i++) {
		if (s[i] + 1 == s[i + 1]) {
			cnt++;
			res = max(res, cnt);
		} else cnt = 1;
	}
	if (res >= 3) ans++;
}
int main() {
	for (int i = 1; i <= 12; i++) {
		for (int j = 1; j <= mday[i]; j++) {
			string s = "2022";
			s += month[i];
			if (j < 10) s += '0';
			s += to_string(j);
			cheak(s);
		}
	}

	cout << ans;
	return 0;
}

C 刷题统计

思路 先算周数,再算天数,注意开longl ong
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long

ll a, b, n;
ll ans = 0;
int main() {
	cin >> a >> b >> n;
	ll week = 0;
	ll k = 5 * a + 2 * b;
	week = n / k;
	n %= k;
	if (5 * a < n) {
		n -= 5 * a;
		ans += 5;
		ans += n / b;
		if (n % b != 0) ans++;
	} else {
		ans += n / a;
		if (n % a != 0) ans++;
	}
	ans += week * 7;

	cout << ans;
	return 0;
}

D 修剪灌木

思路 找规律,最大值为离两端的距离*2的较大者
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;

int n;
int main() {
	cin >> n;

	for (int i = 1; i <= n; i++) cout << 2 * max(n - i, i - 1) << endl;
	return 0;
}

E X进制减法

思路 简单数学计算,当进制X_i最小时,A-B最小
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 1e9 + 7;

ll n, m;
ll ma, mb;
stack<ll> a, b;
ll x, y;
ll ans, res = 1;
int main() {
	cin >> n;
	cin >> ma;
	for (int i = 1; i <= ma; i++) cin >> m, a.push(m);
	cin >> mb;
	for (int i = 1; i <= mb; i++) cin >> m, b.push(m);

	int x, y;
	while (!a.empty()) {
		x = a.top(), a.pop();
		if (!b.empty()) y = b.top(), b.pop();
		else y = 0;
		ans += (x - y + mod) % mod * res % mod;
		ans %= mod;
		res *= max(2, max(x, y) + 1);
		res %= mod;
	}

	cout << ans;
	return 0;
}

F 统计子矩阵

思路 暴力前缀和过不了,得用双指针优化下
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 5e2 + 5;

ll a[N][N], s[N][N];
int n, m;
ll ans, k;
int main() {
	cin >> n >> m >> k;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> a[i][j];
			s[j][i] = s[j][i - 1] + a[i][j];
		}
	}
	
	for (int u = 1; u <= n; u++) {
		for (int d = u; d <= n; d++) {
			int l = 1, r = 1;
			ll sum = s[1][d] - s[1][u - 1];
			while (r <= m) {
				if (sum <= k) {
					ans += r - l + 1;
					r++;
					sum += s[r][d] - s[r][u - 1];
				} else {
					sum -= s[l][d] - s[l][u - 1];
					l++;
				}
			}
		}
	}
	
	cout << ans;
	return 0;
}

G 积木画

思路 找规律递推
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e7 + 5;
const ll mod = 1000000007;

ll dp[N];
int n;
int main() {
	cin >> n;
	dp[1] = 1;
	dp[2] = 2;
	dp[3] = 5;

	for (int i = 4; i <= n; i++) {
		dp[i] = 2 * dp[i - 1] + dp[i - 3];
		dp[i] %= mod;
	}

	cout << dp[n];
	return 0;
}

H 扫雷

思路 直接搜索会暴,考虑优化,由于雷一定会在(x-r,x+r)的范围内,所以采用二分查找出两个边界,循环该范围内的雷即可
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 5e4 + 5;

struct node {
	int x, y;
	int r;
	bool is;
} a[N], b[N];
int ans = 0;
double len(int x1, int y1, int x2, int y2) {
	return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
bool cmp(node a, node b) {
	return a.x < b.x;
}
int n, m;
void boom(node b) {
	int lmid, rmid;
	int L = 1, R = n;
	while (L <= R) {
		lmid = (L + R) / 2;
		if (a[lmid].x < b.x - b.r) L = lmid + 1;
		else R = lmid - 1;
	}
	lmid = L;
	L = 1, R = n;
	while (L <= R) {
		rmid = (L + R) / 2;
		if (a[rmid].x <= b.x + b.r) L = rmid + 1;
		else R = rmid - 1;
	}

	for (int i = lmid; i <= rmid; i++) {
		if (!a[i].is && b.r >= len(b.x, b.y, a[i].x, a[i].y)) {
			ans++;
			a[i].is = 1;
			boom(a[i]);
		}
	}
}

int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> a[i].x >> a[i].y >> a[i].r;
	for (int i = 1; i <= m; i++) cin >> b[i].x >> b[i].y >> b[i].r;
	sort(a + 1, a + 1 + n, cmp);

	for (int i = 1; i <= m; i++) boom(b[i]);

	cout << ans;
	return 0;
}

I 李白打酒加强版

思路 简单动态规划
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 1e9 + 7;

int n, m;
ll dp[205][105][105];
int main() {
	cin >> n >> m;
	dp[0][0][2] = 1;
	
	for (int i = 0; i < n + m; i++) {
		for (int j = 0; j < m; j++) {
			for (int k = 0; k <= m; k++) {
				if (dp[i][j][k]) {
					if (k > 0) dp[i + 1][j + 1][k - 1] = (dp[i + 1][j + 1][k - 1] + dp[i][j][k]) % mod;
					if (k <= 50) dp[i + 1][j][k * 2] = (dp[i + 1][j][k * 2] + dp[i][j][k]) % mod;
				}
			}
		}
	}
	
	cout << dp[n + m][m][0];
	return 0;
}

J 砍竹子

思路 每次砍最大的,用堆实现,把连续的一段当作一个整体,注意用sqrtl
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5 + 5;

ll magic(ll h) {
	ll s = h / 2 + 1;
	s = floor(sqrtl(s));
	return s;
}
int n;
ll a[N];
ll ans = 0;
ll l[N];
struct node {
	ll h;
	ll i;
	friend bool operator<(node a, node b) {
		if (a.h == b.h) return a.i < b.i;
		return a.h < b.h;
	}
};
priority_queue<node> q;
int main() {
	cin >> n;
	for (int i = 1; i <= n + 1; i++) l[i] = i - 1;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		q.push({a[i], i});
	}

	while (1) {
		node ma = q.top();
		q.pop();
		if (ma.h == 1) break;
		ll x = ma.i;
		while (a[l[x]] == ma.h) {
			q.pop();
			x = l[x];
			l[ma.i] = l[x];
		}
		a[ma.i] = magic(ma.h);
		q.push({magic(ma.h), ma.i});
		ans++;
	}

	cout << ans;
	return 0;
}

posted @ 2024-03-02 15:12  史上最速败犬  阅读(112)  评论(0)    收藏  举报