2024CCPC长春邀请赛暨吉林省赛个人补题EFGIL

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;
}

你可能感兴趣的:(CCPC补题,c++,算法,开发语言,数据结构,图论)