Codeforces Round #693 (Div. 3) 解题报告

题目链接:https://codeforces.com/contest/1472

A. Cards for Friends

题目大意

一张纸长为w,宽为h,如果w或h是偶数,那么可以将其分为两半张纸,两张纸重复同样动作,问一张纸能否分成不低于n份

思路

将w,h分别分解,一直除以2,直到不能除为止,分成t1,t2份,那么一共有t1*t2份。

这里可以暴力除,也可以直接用位运算,也就是lowbit(取二进制中从最后一个1的位置开始剩下的数)。

AC代码

暴力

#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

题目大意

n块糖,重量要么是1,要么是2,问能否分成相同重量的两份

思路

求出1的个数t1,2的个数t2,总重量s。

如果s是奇数,肯定不行;

如果分成两半,每人分到的重量是奇数,但是没有重量为1的糖果,那也不行。

AC代码

#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

题目大意

n个数存数组a,从第i个位置开始,中间位置tt初始化为i,然后每次可以跳a[tt]的距离。

如果tt<=n,那么可以继续跳,否则结束游戏,tmp为中途跳的权值和,现在问这个tmp的最大值是多少。

思路

每个位置都可以一直跳,跳出n,如果从左往右遍历的话,举个例子,如果1可以跳到6,3可以跳到6,那么这里6就跳了两回了,多了好多重复操作,不过我们可以从后往前遍历,那么可以相当于记忆化,跳一次足够了。

AC代码

#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

题目大意

n个石子,两个人轮流取,取完为止。Alice先取,Bob后取。

如果Alice取的石头的重量wi为偶数,那么她的分数就会加wi,否则不加;

如果Bob取的石头的重量wi为奇数,那么他的分数就会加wi,否则不加。

问最后谁赢或者平局。

思路

要我选,肯定每次选最重的呀,能加分最好,如果我加不了分,那肯定是你加分了呀,不行,不能给你加,取他。

AC代码

#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

题目大意

n个孩子 排队拍照,每个孩子都有长宽属性wi,hi,如果i要排在j的前面,那么必须得满足wi<wj&&hi<hj或者wi<hj&&hi<wj.

现在问对于每个孩子i,输出一个可以排在他前面的孩子的下标(任意),如果不存在,则输出-1

思路

首先,如果规定wi是(wi,hi)之中的较小值,hi是(wi,hi)之中的较大值,那么只需要看是否满足wi<wj&&hi<hj这个条件即可

然后可以按照先wi后hi排序,保证左边w小于等于右边的w;

双指针的思想,i,j。i遍历数组,j追逐,如果a[j].w<a[i].w的话那么tmp就更新a[j].h的最小值, id是更新最小值的位置,如果此时tmp<a[i].h的话,那么此时id位置的这个小孩可以站在a[i].id这个孩子前面啦。

AC代码

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

猜你喜欢

转载自blog.csdn.net/weixin_43911947/article/details/112217993