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题

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题5题

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题4题