Codeforces Round 857 (Div. 2)

C (构造 数论)

https://codeforces.com/contest/1801/problem/A
题意:给定一个nm矩阵,要求任意一个22方格所有数异或和等于其所有对角22方格异或和,并要求不同的数尽量多。
n,m<=200
题解:不妨加强条件,对任意一个2
2方格使其异或和为0,并且使得每一个数均不相同,即可满足条件。
注意到22方格中有四个数,而对于0~2^k-1连续的数异或和为0,故我们考虑使得任意一个22方格满足其末位连续。即为0 1 2 3。
我们首先对两行进行构造,当按照上述填法时可以保证任意2*2方格异或和=0,而每2行最多用去400个数,故我们只需每次从512的倍数开始赋值即可使得每相邻两行的低8位连续,高位可消去。
代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[300][300];

int check(int x){
	int k=1;
	while(1){
		if(x<=(1<<k)&&x>(1<<(k-1))) return (1<<k);
		else k++;
	}
}
void solve(){
	unsigned long long cnt=0;
	int p=512;
	int n,m;cin>>n>>m;
	cout<<n*m<<endl;
	for(int i=1;i<=n;i+=2){
		for(int j=1;j<=m;j+=2){
			a[i][j]=cnt,a[i][j+1]=cnt+1,a[i+1][j]=cnt+2,a[i+1][j+1]=cnt+3;
			cnt+=4;
		}
		cnt=p;
		p+=512;
	}
	for(int i=1;i<=n;i++){
	for(int j=1;j<=m;j++){
	cout<<a[i][j];
	if(j!=m) cout<<" ";
	}
	cout<<endl;
	}
}
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0); 
cout.tie(0);

	int T;cin>>T;
	while(T--) solve();
}

D (贪心)

https://codeforces.com/contest/1802/problem/D
题意:有n个商店,在每个商店必须买一个物品,可以买给A花费ai也可以买给B花费bi,求二者礼物中各自最贵的礼物的最小差值,要求每个人都要有礼物。
n<=5e5
题解:观察数据范围复杂度应该是nlogn,由于最大值会覆盖,我们必然需要按大小排序,由于每人都要有礼物,所以我们枚举其中某一个的最大值。我们对ai从小到大排序,然后枚举ai最大值,对于大于i的位置,必然选取b,对于小于i的位置,可选可不选。
对于>i位置,如果最大值maxb>ai,那么我们直接选取其作为最大值即可,否则我们二分剩余的b,得到最接近ai的数以更新答案。可以用两个mutiset维护小于i位置的b和大于i位置的b,复杂度为O(nlogn)。
代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+100;

void solve(){
	int n;cin>>n;
	vector<pair<int,int> >a(n);
	multiset<int> s1,s2;
	for(int i=0;i<n;i++){
		cin>>a[i].first>>a[i].second;
		s2.insert(a[i].second);
	}
	sort(a.begin(),a.end());
	int ans=1e9;
	for(int i=0;i<n;i++){
		auto [x,y]=a[i];
		s2.erase(s2.lower_bound(y));
		if(!s2.empty()){
			int mx=*prev(s2.end());
			if(mx>=x) ans=min(mx-x,ans);
			else{
				ans=min(ans,x-mx);
				auto it=s1.lower_bound(x);
				if(it!=s1.end()) ans=min(ans,*it-x);
				if(it!=s1.begin()) ans=min(ans,x-*prev(it));
			}
		}
		else{
			auto it=s1.lower_bound(x);
			if(it!=s1.end()) ans=min(ans,*it-x);
			if(it!=s1.begin()) ans=min(ans,x-*prev(it));
		}
		s1.insert(y);
	}
	cout<<ans<<endl;
}
signed main(){
	int T;cin>>T;
	while(T--) solve();
}
posted @ 2023-03-10 10:09  wrong,anser  阅读(61)  评论(0)    收藏  举报