2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题3题
Posted 小哈里
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题3题相关的知识,希望对你有一定的参考价值。
2021“MINIEYE杯”中国大学生算法设计超级联赛(3)
Start Time : 2021-07-27 12:00:00 End Time : 2021-07-27 17:00:00
Contest Type : Private Contest Status : Ended
Current Server Time : 2021-07-27 17:31:07
Solved Pro.ID Title Ratio(Accepted / Submitted)
1001 Bookshop 5.37%(8/149)
1002 Destinations 16.00%(4/25)
1003 Forgiving Matching 27.46%(170/619)
1004 Game on Plane 13.67%(598/4376) 计算几何,斜率
1005 Kart Race 0.00%(0/16)
1006 New Equipments II 2.96%(4/135)
1007 Photoshop Layers 26.19%(722/2757) 前缀和
1008 Restore Atlantis II 0.00%(0/6)
1009 Rise in Price 5.63%(162/2877)
1010 Road Discount 16.73%(44/263)
1011 Segment Tree with Pruning 42.75%(743/1738) 记忆化
1012 Tree Planting 12.28%(7/57)
1004 Game on Plane
题意:
- 给出n条直线(用两个不重合的点表示),A和B玩游戏,A从n条中选出k条,然后B画一条L,B的惩罚定义为L与这k条有交点的个数。
- A想最大化,B想最小化,假设都是最优策略,求B获得的惩罚。
思路:
- 两条直线不存在公共点当且仅当它们平行即斜率相同,因此Bob 的最优策略一定是避开斜率出现次数最多的那些直线,与之平行并与其他所有直线相交。Alice 为了让Bob 与尽量多的直线相交,最优策略就是最小化斜率出现次数的最大值,所以不断从每种斜率的直线中各选一种即可。时间复杂度O(n log n)。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
struct hash_pair{
template <class T1, class T2>
size_t operator()(const pair<T1, T2>& p)const{
auto hash1 = hash<T1>{}(p.first);
auto hash2 = hash<T2>{}(p.second);
return hash1 ^ hash2;
}
};
unordered_map<pair<int,int>, int, hash_pair>mp;
int f[maxn];
int main(){
ios::sync_with_stdio(false);
int T; cin>>T;
while(T--){
mp.clear();
int n; cin>>n;
for(int i = 1; i <= n; i++){
int x1,y1,x2,y2; cin>>x1>>y1>>x2>>y2;
int dx=x2-x1,dy=y2-y1;
if(dx==0)dy=1;
else if(dy==0)dx=1;
else{
if(dx<0)dx=-dx,dy=-dy;
int d=gcd(abs(dx),abs(dy));
dx /= d, dy /= d;
}
mp[make_pair(dx,dy)]++;
}
for(int i = 1; i <= n; i++)f[i]=0;
for(auto i : mp){
for(int k=1; k<=i.second; k++)f[k]++;
}
for(int i=1, j=1; i <= n; i++){
while(!f[j])j++;
f[j]--;
cout<<i-j<<"\\n";
}
}
return 0;
}
1007 Photoshop Layers
题意:
- 有n个图层,编号1-n,每个图层有模式1或2,以及6位16进制的RGB颜色。从前往后叠加颜色,遇到模式1就覆盖,遇到模式2就相加,如果超过FF则为FF。
- q个询问,每次问[l,r]图层叠加后的颜色
思路:
- 预处理出 f[i] 表示图层 i 左侧第一个合成方式为1的图层。对于每个询问,求出 r 左
侧第一个合成方式为“普通” 的图层fr,则中间的部分都是“线性减淡”,可以用前缀和求出结
果,最后与255 取最小值。 - 时间复杂度O(n + q)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
int m[maxn], last[maxn];
int r[maxn], g[maxn], b[maxn];
int main(){
ios::sync_with_stdio(false);
int T; scanf("%d", &T);
while(T--){
int n, q; scanf("%d%d", &n, &q);
for(int i = 1; i <= n; i++){
int x; scanf("%d%X",&m[i],&x);
last[i] = (m[i]==1?i:last[i-1]);
b[i]=b[i-1]+(x&255); x>>=8;
g[i]=g[i-1]+(x&255); x>>=8;
r[i]=r[i-1]+(x);
}
while(q--){
int x, y; scanf("%d%d",&x,&y);
int xx = max(x, last[y]);
printf("%02X%02X%02X\\n",min(r[y]-r[xx-1],255), min(g[y]-g[xx-1],255), min(b[y]-b[xx-1],255));
}
}
return 0;
}
1011 Segment Tree with Pruning
题意:
- 给出n和k,求对1-n每k个为一个最小区间建立的线段树有多少个节点
思路:
- 找规律找了两个小时发现并没有规律
- 直接暴力+记忆化就过了
- 证明:线段树上代表区间长度相同的节点的子树点数相同,且最多只有O(log n) 种本质不同的区间长度
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
map<LL,LL>ma;
LL n, k, cnt=0;
LL build(LL l, LL r){
if(ma.count(r-l))return ma[r-l];
if(r-l+1<=k){
return 1;
}
LL mid = (l+r)/2, tmp = 1;
tmp += build(l,mid);
tmp += build(mid+1,r);
return ma[r-l] = tmp;
}
int main(){
int T; cin>>T;
while(T--){
ma.clear();
cin>>n>>k;
cnt = build(1,n);
cout<<cnt<<"\\n";
}
return 0;
}
以上是关于2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题3题的主要内容,如果未能解决你的问题,请参考以下文章
2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题4题
2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题5题
2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题5题
2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题2题