fl0ppy-

导航

ABC481解题报告

ABC481解题报告

A

#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N = 500007;
inline int read(){
	int x = 0; bool f = 1; char c = getchar();
	for(; !isdigit(c); c = getchar()) if(c == '-') f = 0;
	for(; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
	return f ? x : -x;
}

main(){
	int a = read(), b = read();
	int c = a + b;
	string s = to_string(c);
	cout << s.length() << endl;
}

Submission


B

#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N = 5e5 + 7;
inline int read(){
	int x = 0; bool f = 1; char c = getchar();
	for(; !isdigit(c); c = getchar()) if(c == '-') f = 0;
	for(; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
	return f ? x : -x;
}
int n, k, a[N];
main(){
	n = read(), k = read();
	for(int i = 1; i <= n; ++i){
		a[i] = read();
	}
	int ans = 0;
	for(int i = 1; i <= n; ++i){
		if(a[i] == k) ++ans;
	}
	for(int i = 1; i < n; ++i){
		if((a[i] < k && a[i + 1] > k) || (a[i] > k && a[i + 1] < k)){
			++ans;
		}
	}
	cout << ans << endl;
	exit(0);
}

Submission


C

#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N = 500007;
inline int read(){
	int x = 0; bool f = 1; char c = getchar();
	for(; !isdigit(c); c = getchar()) if(c == '-') f = 0;
	for(; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
	return f ? x : -x;
}
int Q;

main(){
	Q = read();
	map<string, int>mp;
	int tmp = 1;
	while(Q--){
		string s;
		cin >> s;
		if(mp[s]){
			cout << mp[s] << endl;
			continue;
		}
		else{
			mp[s] = tmp++;
			cout << mp[s] << endl;
			continue;
		}
	}
}

Submission


D

一眼最短路。

怎么做呢?

可以先读完每个边,然后遍历每个点,看它能到的所有点,其中到编号最小的点的边权自然为零,其他都是一,重新建图即可。

最后跑一遍Dijkstra

Code:

#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N = 500007;
inline int read(){
	int x = 0; bool f = 1; char c = getchar();
	for(; !isdigit(c); c = getchar()) if(c == '-') f = 0;
	for(; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
	return f ? x : -x;
}
int n, m, s, t;
vector<int> e[N];
vector<pair<int, int>> e1[N];
int dis[N];
bool vis[N];
// const int III = 1000000000;
inline void dij(int s){
	priority_queue<pair<int, int>> q1;
	memset(dis, 0x3f, sizeof dis);
	dis[s] = 0;
	q1.push({0, s});
	while(q1.size()){
		int x = q1.top().second; q1.pop();
		if(vis[x]){
			continue;
		}
		vis[x] = 1;
		for(const auto tt : e1[x]){
			int y = tt.first, w = tt.second;
			if(dis[y] > dis[x] + w){
				dis[y] = dis[x] + w;
				q1.push({-dis[y], y});
			}
		}
	}

}
main(){
	n = read(), m = read(), s = read(), t = read();
	for(int i = 1; i <= m; ++i){
		int u = read(), v = read();
		e[u].push_back(v);
	}
	for(int i = 1; i <= n; ++i){
		if(e[i].size()){
			stable_sort(e[i].begin(), e[i].end());
			for(const auto o : e[i]){
				if(o == *e[i].begin()){
					e1[i].push_back({o, 0});
					continue;
				}
				e1[i].push_back({o, 1});
			}
		}
		continue;
	}
	dij(s);
	cout << (dis[t] != 0x3f3f3f3f3f3f3f3f ? dis[t] : -1) << endl;
}

Submission


E

额,要用到神秘极角排序,而且赛时吃了6发,精度太烦人了csdn图片Base64。

相当于过原点砍一刀下去最多的一半能留多少个星星。

我们用 PII 来指代 \(180^{\circ}\)。

用神秘 atan2 算出来每个点的方位角,那这样会有负数,我们直接用破环成链思想,每个加上 \(360^{\circ}\)。

然后滑动窗口,对于每个左端点 \(l\in[1,n]\),定义

\[r(l)=\max\{\,r:\ \theta_r-\theta_l<\pi,\ r\ge l\,\}, \]

维护单个右指针 \(r\),初始 \(r=1\)。对 \(l=1,2,\dots,n\) 依次执行:

\[r\leftarrow\max(r,l),\qquad \text{当 } r<2n \text{ 且 } \theta_{r+1}-\theta_l<\pi:\ r\leftarrow r+1, \]

则当前窗口长度为 \(r-l+1\),答案取

\[\text{ans}=\max_{1\le l\le n}\bigl(r(l)-l+1\bigr). \]

由于 \(\theta\) 单调,\(\theta_r-\theta_l<\pi\) 关于 \(l\) 单调,故 \(r(l)\) 随 \(l\) 不减,双指针总移动量为 \(O(n)\),很有搞头。

#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N = 400007;
const long double PII = acosl(-1.0L);
inline int read(){
	int x = 0; bool f = 1; char c = getchar();
	for(; !isdigit(c); c = getchar()) if(c == '-') f = 0;
	for(; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
	return f ? x : -x;
}
long double arr[N];
int n;
main(){
	int Q = read();
	while(Q--){
		n = read();
		for(int i = 1; i <= n; ++i){
			int x = read(), y = read();
			arr[i] = atan2l(y, x);
		}
		sort(arr + 1, arr + n + 1);
		for(int i = n + 1; i <= (n << 1); ++i){
			arr[i] = arr[i - n] + (PII * 2.0L);
		}
		int ans = 0, r = 1;
		for(int l = 1; l <= n; ++l){
			if(r < l) r = l;
			while(r < (n << 1) && (arr[r + 1] - arr[l] < PII)){
				++r;
			}
			ans = max(ans, r - l + 1);
		}
		cout << ans << endl;
	}
	exit(0);
}

Submission

posted on 2026-10-24 23:32  fl0ppy-  阅读(18)  评论(0)    收藏  举报