第14届蓝桥杯B组国赛

子2023

#include <bits/stdc++.h>
using namespace std;
using LL = long long;

void solve() {

	vector<int> Q;
	for (int i = 1 ; i <= 2023 ; ++i) {
		int x = i;
		vector<int> tmp;
		while (x) {
			int y = x % 10;
			if (y == 2 || y == 0 || y == 3) {
				tmp.push_back(y);
			}
			x /= 10;
		}
		reverse(tmp.begin() , tmp.end());
		for (auto y : tmp) {
			Q.push_back(y);
		}
	}

	int SZ = Q.size();
	vector<LL> dp3(SZ+1),dp23(SZ+1),dp023(SZ+1),dp2023(SZ+1);
	for (int i = SZ - 1 ; i >= 0 ; --i) {
		dp3[i] = dp3[i + 1] + (Q[i] == 3); 
	}
	for (int i = SZ - 1 ; i >= 0 ; --i) {
		dp23[i] = dp23[i + 1] + (Q[i] == 2) * dp3[i + 1];
	}
	for (int i = SZ - 1 ; i >= 0 ; --i) {
		dp023[i] = dp023[i + 1] + (Q[i] == 0) * dp23[i + 1];
	}
	for (int i = SZ - 1 ; i >= 0 ; --i) {
		dp2023[i] = dp2023[i + 1] + (Q[i] == 2) * dp023[i + 1];
	}

	cout << dp2023[0] << "\n";
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int T = 1;
	while (T--) {
		solve();
	}

	return 0;
}

双子数

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 5E6 + 5;

int vaild[N];
vector<int> pri;

void init(int n) {
	vaild[1] = 1;
	for (int i = 2 ; i <= n ; ++i) {
		if (!vaild[i]) {
			pri.push_back(i);
		}
		for (int j = 0 ; j < pri.size() && i <= n / pri[j] ; ++j) {
			vaild[i * pri[j]] = 1;
			if (i % pri[j] == 0) {
				break;
			}
		}
	}
}

LL func(LL tar) {
	
	LL ans = 0;
	int SZ = pri.size();

	for (int i = 0 ; i + 1 < SZ ; ++i) {
		if (1LL * pri[i] * pri[i] > tar) break;
		auto check = [&] (int md) {
			LL x = 1LL * pri[i] * pri[md];
			if (x <= tar / x) return true;
			else return false;
		};
		int l = i + 1 , r = SZ - 1;
		while (l < r) {
			int md = (l + r + 1) / 2;
			if (check(md)) l = md;
			else r = md - 1;
		}
		if (check(l)) {
			ans += l - i;
		}

	}
	return ans;
}

void solve() {
	LL l = 2333 , r = 23333333333333;
	int n = sqrt(r) + 5;
	init(n);
	LL L,R;
	L = func(l - 1);
	R = func(r);
	// cout << L << " " << R << "\n";
	cout << R - L << "\n";
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int T = 1;
	while (T--) {
		solve();
	}

	return 0;
}

班级活动

#include <bits/stdc++.h>
using namespace std;
using LL = long long;

void solve() {
	
	int n;
	cin >> n;
	
	vector<int> a(n + 1) , num(n + 1);
	for (int i = 1 ; i <= n ; ++i) {
		cin >> a[i];
		num[a[i]] += 1;
	}

	int cnt1 = 0 , cnt2 = 0;
	for (int i = 1 ; i <= n ; ++i) {
		if (num[i]) {
			if (num[i] > 2) cnt2 += num[i] - 2;
			else if (num[i] == 1) cnt1 += 1; 
		} 
	}

	int ans = 0;
	if (cnt1 <= cnt2) {
		ans = cnt2;
	} else {
		ans += cnt2;
		cnt1 -= cnt2;
		ans += cnt1 / 2;
	}

	cout << ans << "\n";
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int T = 1;
	while (T--) {
		solve();
	}

	return 0;
}

合并数列

#include <bits/stdc++.h>
using namespace std;
using LL = long long;

void solve() {
	
	int n,m;
	cin >> n >> m;
	
	map<LL,int> mp;	
	vector<LL> a(n + 1) , b(m + 1) , sa(n + 1) , sb(m + 1);
	for (int i = 1 ; i <= n ; ++i) {
		cin >> a[i];
		sa[i] = sa[i - 1] + a[i];
		mp[sa[i]] += 1;
	}
	for (int i = 1 ; i <= m ; ++i) {
		cin >> b[i];
		sb[i] = sb[i - 1] + b[i];
		mp[sb[i]] += 1;
	}

	int ans = 0;
	for (auto f : mp) {
		if (f.second == 1) {
			ans += 1;
		}
	}

	cout << ans << "\n";
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int T = 1;
	while (T--) {
		solve();
	}

	return 0;
}

AB路线

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 1005 , inf = 1E9;
const int dx[] = {0 , 0 , -1 , 1} , dy[] = {1 , -1 , 0 , 0};

int n,m,K;
int s[N][N];
int dis[N][N][11];

void solve() {

	cin >> n >> m >> K;
	for (int i = 1 ; i <= n ; ++i) {
		for (int j = 1 ; j <= m ; ++j) {
			char c;
			cin >> c;
			if (c == 'B') s[i][j] = 1;
		}
	}

	memset(dis , -1 , sizeof dis);
	
	queue<array<int,3>> Q;
	Q.push({1 , 1 , K - 1});
	dis[1][1][K - 1] = 0;

	while (!Q.empty()) {
		auto f = Q.front();
		Q.pop();
		int x = f[0] , y = f[1] , rem = f[2];
		for (int k = 0 ; k < 4 ; ++k) {
			
			int nx = x + dx[k] , ny = y + dy[k];
			if (nx < 1 || nx > n || ny < 1 || ny > m) continue;
			
			if (rem > 0) {
				if (s[nx][ny] == s[x][y]) {
					if (dis[nx][ny][rem - 1] == -1) {
						dis[nx][ny][rem - 1] = dis[x][y][rem] + 1;
						Q.push({nx , ny , rem - 1});
					}
				}
			} else {
				if (s[nx][ny] != s[x][y]) {
					if (dis[nx][ny][K - 1] == -1) {
						dis[nx][ny][K - 1] = dis[x][y][rem] + 1;
						Q.push({nx , ny , K - 1});
					}
				}
			}

		}
	}
	
	const int inf = 2E9;
	int ans = inf;
	for (int i = 0 ; i <= K ; ++i) {
		if (dis[n][m][i] != -1) {
			ans = min(ans , dis[n][m][i]);
		}
	}

	if (ans == inf) {
		ans = -1;
	}

	cout << ans << "\n";
}

int main() {
	
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int T = 1;
	while (T--) {
		solve();
	}

	return 0;
}

删边问题

注意要考虑原图本身就存在两个及以上连通块的情况

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 2E5 + 5;

LL w[N],s[N];
vector<array<int,2>> g[N],que;
int tot,dfn[N],low[N];

void dfs(int u,int id) {
	s[u] = w[u];
	dfn[u] = low[u] = ++tot;
	for (auto f : g[u]) {
		int v = f[0] , id2 = f[1];
		if (!dfn[v]) {
			dfs(v , id2);
			s[u] += s[v];
			low[u] = min(low[u] , low[v]);
			if (low[v] > dfn[u]) {
				que.push_back({u , v});
			}
		} else if (id != id2) {
			low[u] = min(low[u] , dfn[v]);
		}
	}
}

void solve() {

	int n,m;
	cin >> n >> m;
	
	LL sum = 0;
	for (int i = 1 ; i <= n ; ++i) {
		cin >> w[i];
		sum += w[i];
	}
	for (int i = 1 ; i <= m ; ++i) {
		int u,v;
		cin >> u >> v;
		g[u].push_back({v , i});
		g[v].push_back({u , i});
	}

	int scc = 0 , p1 = 0 , p2 = 0;
	for (int i = 1 ; i <= n ; ++i) {
		if (!dfn[i]) {
			++scc;
			dfs(i , 0);
			if (p1 == 0) p1 = i;
			else if (p2 == 0) p2 = i;
		}
	}

	if (scc >= 2) {
		if (scc > 2) {
			cout << "-1\n";
		} else if (scc == 2) {
			if ((int)que.size() == m) {
				cout << "-1\n";
			} else {
				cout << abs(s[p1] - s[p2]) << "\n";
			} 
		}
		return;
	}

	const LL inf = 1E18;
	LL ans = inf;
	for (auto f : que) {
		int u = f[0] , v = f[1];
		LL mn = min(s[u] , s[v]);
		ans = min(ans , abs(sum - mn - mn));
	}

	if (ans == inf) {
		ans = -1;
	}

	cout << ans << "\n";
}

int main() {

	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int T = 1;
	while (T--) {
		solve();
	}

	return 0;
}

数三角

基本思路就是枚举等腰三角形的顶点,把它想象成圆心,转圈,注意去除三点共线的情况

#include <bits/stdc++.h>
using namespace std;
using LL = long long;

void solve() {
	
	int n;
	cin >> n;

	set<array<int,2>> S;
	vector<array<int,2>> Node(n + 1);
	for (int i = 1 ; i <= n ; ++i) {
		int x,y;
		cin >> x >> y;
		Node[i] = {x , y};
		S.insert({x , y});
	}

	auto get = [&] (int x1,int y1,int x2,int y2) -> LL {
		LL ans = 1LL * (x1 - x2) * (x1 - x2) + 1LL * (y1 - y2) * (y1 - y2);
		return ans;
	};

	LL ans = 0;
	for (int i = 1 ; i <= n ; ++i) {
		auto tmp = S;
		int x1 = Node[i][0] , y1 = Node[i][1];
		tmp.erase({x1 , y1});
		unordered_map<LL,int> mp;
		int cnt = 0;
		for (auto f : tmp) {
			int x2 = f[0] , y2 = f[1];
			LL dis = get(x1 , y1 , x2 , y2);
			ans += mp[dis];
			mp[dis] += 1;
			int x3 = 2 * x1 - x2 , y3 = 2 * y1 - y2;
			if (tmp.count({x3 , y3})) ++cnt; 
		}
		ans -= cnt / 2;
	}

	cout << ans << "\n";
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int T = 1;
	while (T--) {
		solve();
	}

	return 0;
}

抓娃娃

注意到性质 \(max(r_i - l_i) \leq min(R_i - L_i)\).
那么只要区间包含线段的中心即可.
注意到中心除 \(2\) 可能会有精度问题,那么我们坐标乘 \(2\) 即可.

#include <bits/stdc++.h>
using namespace std;
using LL = long long;

void solve() {
	
	int n,m;
	cin >> n >> m;
	
	vector<int> x;
	for (int i = 1 ; i <= n ; ++i) {
		int l,r;
		cin >> l >> r;
		x.push_back(l + r);
	}
	sort(x.begin() , x.end());
	
	for (int i = 1 ; i <= m ; ++i) {
		int L,R;
		cin >> L >> R;
		L = L * 2 , R = R * 2;
		int l = lower_bound(x.begin() , x.end() , L) - x.begin();
		int r = upper_bound(x.begin() , x.end() , R) - x.begin();
		cout << r - l << "\n";
	}

}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int T = 1;
	while (T--) {
		solve();
	}

	return 0;
}

\(n^22^n\)


posted @ 2024-05-29 17:28  xqy2003  阅读(14)  评论(0编辑  收藏  举报