训练情况
赛后反思
C题没想明白,但是发现了数列一定是不增加的,另外第一次出现的数字,那个位置就必须是那个数字,剩下可能是乘法原理之类的东西吧,但是没做出来
A题
判断字符串第一位和最后一位是否一致即可
点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'using namespace std;void solve(){string s; cin>>s;int n = s.size();if(s[0] == s[n-1]) cout<<"YES"<<endl;else cout<<"NO"<<endl;
}signed main(){// int T; cin>>T; while(T--)solve();return 0;
}
B题
我们发现对于两个长度一样的队列,两个窗口会同时关掉,只需要判断数列中是否存在两个相同的元素即可
点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'using namespace std;void solve(){int n; cin>>n;map<int,int> v;bool flag = true;for(int i = 1;i<=n;i++){int x; cin>>x;v[x]++;if(v[x] == 2) flag = false;}if(flag) cout<<"YES"<<endl;else cout<<"NO"<<endl;
}signed main(){// int T; cin>>T; while(T--)solve();return 0;
}
C题
判断是否存在的方法同上题,想要全部拍照显然需要从队列人少的开始,按照队列人数从小到大的顺序拍照,所以我们结构体记录位置和人数,排序后输出即可
点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'using namespace std;struct node{int x,y;
};bool cmp(node x,node y){return x.x > y.x;
}void solve(){int n; cin>>n;vector<node> a(n + 1);map<int,int> v;bool flag = true;for(int i = 1;i<=n;i++){cin>>a[i].x;v[a[i].x]++;if(v[a[i].x] == 2) flag = false;a[i].y = i;}if(flag){cout<<"YES"<<endl;sort(a.begin() + 1,a.end(),cmp);for(int i = n;i;i--){cout<<a[i].y<<" ";}} else cout<<"NO"<<endl;
}signed main(){// int T; cin>>T; while(T--)solve();return 0;
}
E题
首先我们考虑枚举 a,b 数列,位置 m 和 m + 1 的分界点,对于 a 数列求前缀 k 小数之和,对于 b 数列求后缀 k 小数之和,维护和我们考虑使用优先队列存当前最大的数,如果新的数小于最大的数,将最大的数替换成新数,使用堆维护这个操作,最后求出前后缀 k 小数和,遍历分界点答案取小值
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'using namespace std;void solve(){int n,k; cin>>n>>k;vector<int> a(n + 1),b(n + 1);vector<int> pre(n + 1),suf(n + 1);for(int i = 1;i<=n;i++) cin>>a[i];for(int i = 1;i<=n;i++) cin>>b[i];priority_queue<int> s;int sum = 0;for(int i = 1;i<=k;i++) s.push(a[i]),sum += a[i];pre[k] = sum;for(int i = k+1;i<=n;i++){if(a[i] < s.top()){sum -= s.top();s.pop();s.push(a[i]);sum += a[i];}pre[i] = sum;}while(s.size()) s.pop();sum = 0;for(int i = n;i>=n-k+1;i--) s.push(b[i]),sum += b[i];suf[n-k+1] = sum;for(int i = n-k;i;i--){if(b[i] < s.top()){sum -= s.top();s.pop();s.push(b[i]);sum += b[i];}suf[i] = sum;}int ans = LONG_LONG_MAX;for(int i = k;i<=n-k;i++){// cout<<i<<" "<<pre[i]<<" "<<suf[i]<<endl;ans = min(ans,pre[i] + suf[i+1]);}cout<<ans<<endl;
}signed main(){// int T; cin>>T; while(T--)solve();return 0;
}