Dashboard - The 2024 CCPC National Invitational Contest (Changchun) , The 17th Jilin Provincial Collegiate Programming Contest - Codeforces
过题难度 I L G E F
铜奖 1 6
银奖 3 320
金奖 4 391
Problem - I - Codeforces
签到题不解释
// Code Start Here
cout << 21 <
Problem - L - Codeforces
模拟匹配的过程,偶数情况答案很明显,奇数情况分类讨论即可
// Code Start Here
int t;
cin >> t;
while(t--){
int k , x , y;
cin >> k >> x >> y;
if(k == 1)cout << x + y << endl;
else{
if(k % 2 == 1){
int temp = k / 2;
int cnt = min(x ,y/temp);
int ans = cnt;
y -= cnt * temp;
x -= cnt;
if(y == 0)ans += x / k;
else if(x == 0)ans += y/(temp + 1);
else{
temp = k - 2 * y;
x -= temp;
if(x >= 0){
ans += x / k;
ans++;
}
}
cout << ans << endl;
}
else{
cout << (2 * y + x) / k <
Problem - G - Codeforces
我们把往右下滚动的过程看作是找一个单调的,可合并的区间,找这个区间的最大长度即可
struct line{
int l , r , y;
friend bool operator >(line &a , line &b){
if(a.y == b.y)return a.l < b.l;
return a.y > b.y;
};
};
int32_t main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
// Code Start Here
int t;
cin >> t;
while(t--){
int n;
cin >> n;
vector a(n);
for(auto &[l , r , y] : a)cin >> l >> r >> y;
sort(all(a),greater<>());
int sx , sy;
cin >> sx >> sy;
for(auto [l , r , y] : a){
if(y == sy){
if(sx > l && sx < r)sx = r;
}
else{
if(sx >l && sx < r && y<= sy)sx = r , sy = y;
}
}
cout << sx << endl;
}
return 0;
}
Problem - E - Codeforces
把题目的不等式变形,有=−,=−,那么与有边的条件就是当且仅当≤∨≤。
考虑将所有点按排序,再考虑按标号从小到大加入每个点以及更新连通情况。 在加入点前,我们只关心每个连通块最小的点,将这些点用一个单调栈维护。 加入时如果小于栈顶则将推入栈,否则将所有≤的非栈顶元素弹出(表 示与这些点连边)并保留栈顶。
// Code Start Here
int n;
cin >> n;
vector> v;
for(int i = 1;i<=n;i++){
int a , b;
cin >> a >> b;
v.push_back({a - i,i - b});
}
sort(all(v),[&](pair a,pair b){
if(a.first == b.first)return a.second < b.second;
return a.first st;
st.push(v[0].second);
for(int i = 1;i= st.top()){
int min_val = st.top();
while(!st.empty() && v[i].second >= st.top())st.pop();
st.push(min_val);
}
else if(v[i].second < st.top())st.push(v[i].second);
}
}
cout << st.size() << endl;
Problem - F - Codeforces
题意:
本次比赛共有编号从1到n的n名选手参与,进行了总共m场1对1的对决:
第i场对决的对手是选手ai和bi;
每场对决包括上半场和下半场:
在对决的上半场,选手ai的得分为xi,选手bi的得分为yi;
在对决的下半场,两名选手ai和bi的确切得分目前不确定,但两人得分之和为zi;
一名选手在一场对决中的得分等于上半场得分和下半场得分之和。换句话说,在第ii场对决中,选手aiai和bibi的可能得分分别为xi+pi和yi+qi,其中0≤pi,qi≤zi,pi+qi=zi。 请注意,所有得分均为非负整数,每名选手至少参与了一场对决。
一名选手的最终得分为:他参与对决中取得的最大得分。一名选手将获得最佳选手奖项,当且仅当他的最终得分严格大于任何其他选手的最终得分。 由于第m场对决下半场得分的不确定性,最佳选手也可能不同。请找出所有可能成为最佳选手的选手。
思路:
发现nm数据范围较大,考虑优化。考虑判断时只枚举参与的比赛,再用一个堆或者multiset维护最大值
struct node{
int x , y , z , idx;
};vector mp[N];
int32_t main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
// Code Start Here
int t;
cin >> t;
while(t--){
int n , m;
cin >> n >> m;
set> s;
for(int i = 1;i<=m;i++){
int a , b , x , y , z;
cin >> a >> b >> x >> y >> z;
mp[a].push_back({x , y , z , i});
mp[b].push_back({y , x , z , i});
int g = abs(x - y);
int sp = max((z - g + 1) / 2,0LL);
s.insert({max(x , y) + sp , i});
}
vector ans;
for(int i = 1;i<=n;i++){
vector> cls;
int max_val= 0 , lpx = 0;
for(auto[x , y , z , idx] : mp[i]){
int g = abs(x - y);
int sp = max((z - g + 1)/2 , 0LL);
s.erase({max(x , y) + sp , idx});
cls.push_back({max(x , y) + sp , idx});
max_val = max(max_val , x + z);
lpx = max(lpx , y);
}
if(!s.empty()){
auto it = prev(s.end());
lpx = max(lpx , it->first);
}
if(max_val > lpx)ans.push_back(i);
for(auto lp : cls)s.insert(lp);
mp[i].clear();
}
cout << sz(ans) << endl;
for(auto i : ans) cout << i << " ";
cout << endl;
}
return 0;
}