Codeforces Round #693 (Div. 3) Problem Solving Report

Subject link: https://codeforces.com/contest/1472

A. Cards for Friends

Topic

A piece of paper is w in length and h in width. If w or h is an even number, then it can be divided into two halves of paper. Repeat the same action for the two pieces of paper and ask whether one piece of paper can be divided into no less than n

Ideas

Decompose w and h separately and keep dividing by 2 until they can't be divided, and divide them into t1 and t2 parts, so there are t1*t2 parts in total.

Here you can divide by force, or you can use bit operations directly, that is, lowbit (take the number remaining from the position of the last 1 in the binary).

AC code

violence

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
	int t; cin >> t;
	while(t --){
		int w, h, n;
		cin >> w >> h >> n;
		int t1 = 1, t2 = 1;
		while(w % 2 == 0) {
			t1 *= 2;
			w /= 2;
		}
		while(h % 2 == 0){
			t2 *= 2;
			h /= 2;
		}
		if(t1 * t2 >= n) puts("YES");
		else puts("NO");
	}
	return 0;
}

lowbit

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(x) x & (-x)
int main(){
	int t; cin >> t;
	while(t --){
		int w, h, n;
		cin >> w >> h >> n;
		int t1 = lowbit(w), t2 = lowbit(h);
		if(t1 * t2 >= n) puts("YES");
		else puts("NO");
	}
	return 0;
}

B. Fair Division

Topic

n pieces of sugar, the weight is either 1 or 2, ask if it can be divided into two parts of the same weight

Ideas

Find the number of 1, t1, the number of 2, t2, and the total weight s.

If s is an odd number, it will definitely not work;

If it is divided into two halves, the weight assigned to each person is an odd number, but there is no candy with a weight of 1, that will not work.

AC code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
	int t; cin >> t;
	while(t --){
		int s = 0, n, t1 = 0, t2 = 0, x;
		cin >> n;
		while(n --){
			cin >> x;
			t1 += (x == 1);
			t2 += (x == 2);
			s += x;
		}
		if(s % 2){
			puts("NO");
			continue;
		}
		s /= 2;
		if(s % 2 && !t1) puts("No");
		else puts("YES"); 
	}
	return 0;
}

C. Long Jumps

Topic

The n numbers are stored in the array a, starting from the i-th position, the middle position tt is initialized to i, and then the distance of a[tt] can be jumped each time.

If tt<=n, then you can continue to jump, otherwise the game ends, tmp is the sum of the weights of the halfway jump, now I ask what the maximum value of this tmp is.

Ideas

Each position can jump all the time, jumping out of n. If you traverse from left to right, for example, if 1 can jump to 6 and 3 can jump to 6, then 6 here has jumped twice, a lot of repeats Operation, but we can traverse from back to front, so it can be equivalent to memoization, one jump is enough.

AC code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 10;
ll a[maxn], dp[maxn]; // dp[i]就是从i位置开始跳出n需要加的权值
int main(){
	int t; cin >> t;
	while(t --){
		int n; scanf("%d",&n);
		for(int i = 1; i <= n; i ++){
			scanf("%lld", &a[i]);
		}
		for(int i = 1; i <= n; i ++) dp[i] = 0;
		ll ans = 0;
		for(int i = n; i >= 1; i --){
			ll d = i + a[i];
			dp[i] += a[i] + (d <= n ? dp[d] : 0);
			ans = max(ans, dp[i]);
		}
		cout << ans << endl;
	}
	return 0;
}

D. Even-Odd Game

Topic

Two people take turns to take n stones until they are finished. Alice takes first, Bob takes second.

If the weight wi of the stone taken by Alice is an even number, then her score will be added wi, otherwise it will not be added;

If the weight wi of the stone taken by Bob is odd, then his score will be added wi, otherwise it will not be added.

Ask who wins or draws in the end.

Ideas

If I want to choose, I must choose the heaviest one every time. The best way to add points. If I can’t add points, then you must have added points. No, I can’t add them to you, take him.

AC code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 10;
ll a[maxn];
int main(){
	int t; cin >> t;
	while(t --){
		int n, x; cin >> n;
		ll t1 = 0, t2 = 0;
		for(int i = 1; i <= n; i ++) {
			cin >> a[i];
		}
		sort(a + 1, a + n + 1, greater<int>()); //从大到小排序
		for(int i = 1; i <= n; i ++){
			if(i % 2 == 1 && a[i] % 2 == 0) t1 += a[i]; //Alice先手 偶数加分
			if(i % 2 == 0 && a[i] % 2 == 1) t2 += a[i]; //Bob后手 奇数加分
		}
		if(t1 > t2) puts("Alice");
		else if(t1 < t2) puts("Bob");
		else puts("Tie");
	}
	return 0;
}

E. Correct Placement

Topic

N children line up to take pictures, and each child has length and width attributes wi, hi. If i is to be ranked before j, then it must satisfy wi<wj&&hi<hj or wi<hj&&hi<wj.

Now ask for each child i, output a subscript (arbitrary) of the child that can be arranged in front of him, if it does not exist, output -1

Ideas

First of all, if it is stipulated that wi is the smaller value among (wi, hi) and hi is the larger value among (wi, hi), then only need to see whether the condition wi<wj&&hi<hj is satisfied

Then you can sort wi first, then hi, to ensure that w on the left is less than or equal to w on the right;

The idea of ​​double pointers, i, j. i traverses the array, j chases, if a[j].w<a[i].w then tmp updates the minimum value of a[j].h, id is the position of the updated minimum value, if tmp<a In the case of [i].h, then the child in id position can stand in front of the child a[i].id at this time.

AC code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(x) x & (-x)
#define pp pair<int, int>
const int maxn = 2e5 + 10;
struct node{
	int x, y, id;
	bool operator < (const node &a) const{
		if(x != a.x) return x < a.x;
		return y < a.y;	
	}
}a[maxn];
int dp[maxn];
int main(){
	int t, n;
	cin >> t;
	while(t --){
		cin >> n;
		for(int i = 1; i <= n; i ++){
			cin >> a[i].x >> a[i].y;
			if(a[i].x > a[i].y) swap(a[i].x, a[i].y);
			a[i].id = i; dp[i] = -1;
		}
		sort(a + 1, a + n + 1);
		int tmp = 0x3f3f3f3f, id = -1, j = 1;
		for(int i = 1; i <= n; i ++){
			while(j < i && a[j].x < a[i].x){
				if(tmp > a[j].y){
					tmp = a[j].y;
					id = a[j].id;
				} j ++;
			}
			if(tmp < a[i].y) dp[a[i].id] = id;
		}
		for(int i = 1; i <= n; i ++){
			if(i > 1) cout << " ";
			cout << dp[i];
		}
		cout << endl;
	}
	return 0;
}

 

Guess you like

Origin blog.csdn.net/weixin_43911947/article/details/112217993