文章目录
- 2024 吉林 CCPC
- L. Recharge(思维、分配)
- G. Platform Game(模拟)
- E. Connect Components (排序、思维)
- D. Parallel Lines
2024 吉林 CCPC
题目链接:
Dashboard - The 2024 CCPC National Invitational Contest (Changchun) , The 17th Jilin Provincial Collegiate Programming Contest - Codeforces
L. Recharge(思维、分配)
- 如果k是偶数,
(x+y*2)/k
- k为奇数,优先使用y+x的组合
G. Platform Game(模拟)
按照 y 进行排序,由于数据范围比较小,可以直接枚举找到小球接下来
落到的平台。
E. Connect Components (排序、思维)
看到连通块第一想到的就是并查集,但实际上用不到。
将公式变换,以a[i]-i
从小到大排序,此时前面的i-b[i]
同样小于后面的就可以
联通。
可以用一个对顶堆来维护。
每次将后面大于当前的点,加入并查集,并弹出。
但是这样会漏掉。
如果以
a[i]-i
和b[i]-i
分别排序,进行两次就可以过。不确定是不是卡过去,大概率不是
这里可以用小顶堆或者栈,如果后续出现一个较大的值,就将所有小于a[ i ].se的弹出去,
他们都可以形成连通块,再将最小值给推进去,这样保证每次都可以用最小值来连接。
int mod=998244353;
struct node{int l,r;
}a[N];
bool cmp(node u,node v){if(u.l==v.l)return u.r<v.r;return u.l<v.l;
}
void solve(){int n;cin>>n;for(int i=1;i<=n;i++){int x,y;cin>>x>>y;a[i].l=x-i;a[i].r=i-y;}sort(a+1,a+1+n,cmp);stack<int>q;q.push(a[1].r);for(int i=2;i<=n;i++){int f=0,tt;if(q.size()) tt=q.top();while(!q.empty()&&a[i].r>=q.top()){f=1;q.pop();}if(f==1){q.push(tt);}else{q.push(a[i].r);}}cout<<(int)q.size()<<'\n';
}
D. Parallel Lines
题意:k条平行线 n个点。判断每一条平行线上,点的x坐标
先暴力用第一个点和所有点,计算斜率。其中必有一个斜率是平行线斜率。
- 判断有哪几个点在一条平行线上:
可以用直线方程, y=kx+b
将 k ,x , y 带入,如果b值相同,说明在同一条直线上。
由于直接求斜率会有误差,可以两边同乘 (x1-x2)
- 剪枝:当 b 值 大于 k 个的时候,说明这个斜率是错误的
- 注意:一条直线上至少有两个点。
PII a[N];
void solve()
{int n,k;cin>>n>>k;fir(i,1,n)cin>>a[i].fi>>a[i].se;fir(i,2,n){int dx=a[i].fi-a[1].fi,dy=a[i].se-a[1].se;map<int,vector<int> > mp;fir(i,1,n){int x=a[i].fi*dy-a[i].se*dx;mp[x].push_back(i);if(mp.size()>k) break; }if(mp.size()==k){int f=0;for(auto it:mp){if(it.se.size()==1) f=1;}if(f) continue;for(auto it:mp){cout<<it.se.size()<<' ';for(auto ii:it.se){cout<<ii<<' ';}cout<<'\n';}return;}}
}