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;
}
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);
}
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;
}
}
}
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;
}
E
额,要用到神秘极角排序,而且赛时吃了6发,精度太烦人了
。
相当于过原点砍一刀下去最多的一半能留多少个星星。
我们用 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);
}
浙公网安备 33010602011771号