【CodeForces】CF Round 648 (Div.2)

CF Round 648 (Div.2)/CF1365

赛时一开始交了两发B错解然后才开始肝A(这也是我掉分的原因),最终大号第一次掉分。

E. Maximum Subsequence Value

有一个有趣的推导。有个猜想,我们只需选择“和”最大的三个数。假设需要选择 (k) 个数 ((k>3)),那么我们从中挑取 (k-1) 个数那么它不会变差,因为挑出来的 (k-1) 个数取不到的位,这 (k) 个数也一定取不到。对于 (k=3),每个位只需要取一个即可,所以如果从中挑选两个数一定不会比这三个数的“和”更大。所以我们枚举选哪三个即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=509;
int n,a[N],ans;
signed main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			for(int k=1;k<=n;k++)
				ans=max(ans,a[i]|a[j]|a[k]);
	printf("%lld",ans);
	return 0;
}

F. Swaps Again

又是个结论题。首先如果这两个数列的数都不一样那么肯定不行。

做这种题有一个小技巧,看我们进行一次 swap 后什么没变。显然,考虑所有形如 ((a_i,a_{n-i+1})) 的数对,无论怎么 swap,这些数对都不会变(顺序会变而已)。所以我们只需要检查两个数列中,((a_i,a_{n-i+1})) 这几个数对构成的可重集合是否相等即可。又因为如果满足上述条件那么一定可以得到结果(我也不知怎么证明),所以判断一下即可。

#include<bits/stdc++.h>
using namespace std;
const int N=509;
struct pr{int x,y;}a[N],b[N];
bool cmp(const pr&i,const pr&j){
	if(i.x==j.x) return i.y<j.y;
	else return i.x<j.x; 
}
int main(){
	int T; cin>>T;
	while(T--){
		int n; scanf("%d",&n);
		for(int i=1;i<=n;i++) a[i].x=a[i].y=b[i].x=b[i].y=0;
		for(int i=1;i<=(n+1)/2;i++) scanf("%d",&a[i].x);
		for(int i=n/2;i>=1;i--) scanf("%d",&a[i].y);
		for(int i=1;i<=(n+1)/2;i++) scanf("%d",&b[i].x);
		for(int i=n/2;i>=1;i--) scanf("%d",&b[i].y);
		for(int i=1;i<=(n+1)/2;i++){
			if(a[i].x>a[i].y) swap(a[i].x,a[i].y);
			if(b[i].x>b[i].y) swap(b[i].x,b[i].y);
		}
		sort(a+1,a+(n+1)/2+1,cmp), sort(b+1,b+(n+1)/2+1,cmp);
		bool ans=1;
		for(int i=1;i<=(n+1)/2;i++)
			ans&=(a[i].x==b[i].x&&a[i].y==b[i].y);
		puts(ans?"Yes":"No");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/TetrisCandy/p/13094850.html