比赛地址:https://acm.ecnu.edu.cn/contest/676/problem/A/

AB感觉都挺难,比赛做了B,A没想出来。A这个数没猜到不会很大,应该打表或者数学分析一下的。==

A:大意就是你需要构造一个n*m的矩阵,要求长宽均>=2的矩阵,四角不能相同。

如果n=2或者m=2很好构造。

其他的,如果n或者m很大则不能构造。
最终结论是n和m最小<=4最大<=6可以构造。

直接爆搜,因为t很大,所以重复出现的直接记录一下。

code:

const int nn = 8;
int a[nn][nn];
bool ok=false;
struct tdata{
	int mp[nn][nn];
	int flag = 0;
};
tdata s[nn][nn];
bool check(int n,int m){
	// for(int i=1;i<=n;i++){
		// for(int j=1;j<=m;j++){
			// cout<<a[i][j];
		// }
		// cout<<endl;
	// }
	// cout<<endl;
	for(int i=1;i<n;i++){
		for(int j=1;j<m;j++){
			for(int k=1;i+k<=n;k++){
				for(int l=1;j+l<=m;l++){
					if(a[i][j]==a[i+k][j]&&a[i][j]==a[i][j+l]&&a[i][j]==a[i+k][j+l])
						return false;
				}
			}
		}
	}
	return true;
}
void dfs(int sum,int n,int m){
	if(ok){
		return;
	}
	int curx = (sum/m)+1;
	int cury = (sum%m)+1;
	if(curx==n&&cury==m){
		if(check(n,m)){
			ok = true;
		}
		return;
	}
	if(ok) return;
	a[curx][cury] = 1;
	dfs(sum+1,n,m);
	if(ok) return;
	if(sum){
		a[curx][cury] = 0;
		dfs(sum+1,n,m);
	}
}
void print(int n,int m){
	cout<<"Yes"<<endl;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++)
			cout<<s[n][m].mp[i][j];
		cout<<endl;
	}
}
void solve()
{
	int n,m;
	cin>>n>>m;
	ok = false;
	if(n==2){
		cout<<"Yes"<<endl;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(i&1) cout<<1;
				else cout<<0;
			}
			cout<<endl;
		}
		return;
	}
	if(m==2){
		cout<<"Yes"<<endl;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(j&1) cout<<1;
				else cout<<0;
			}
			cout<<endl;
		}
		return;
	}
	
	if(min(n,m)<=4&&max(n,m)<=6){
		if(s[n][m].flag){
			print(n,m);
			return;
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++)
				a[i][j] = 0;
		}
		dfs(0,n,m);
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				s[n][m].mp[i][j] = a[i][j];
				// s[m][n].mp[m-j+1][i] = a[i][j];
			}
		}
		s[n][m].flag = 1;
		// s[m][n].flag = 1;
		print(n,m);
	}
	else cout<<"No"<<endl;
}

B:大意就是给出n个长度的a数组和b数组,求两两配对的 (ai+bj)%n,使得总和最大。

贪心做法即可。将每个ai,bj模除后排序。对于任意ai,找一个总和在n以内的。
用map递减排序维护一下,数值不会很大。如果找不到,直接拿最大的来用就可以。

code:

void solve()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		a[i]%=n;
	}
	map<int,int,greater<int>> mp;
	for(int i=1;i<=n;i++){
		cin>>b[i];
		b[i]%=n;
		mp[b[i]]++;
	}
	sort(a+1,a+n+1);
	// sort(b+1,b+n+1);
	ll ans =  0;
	for(int i=1;i<=n;i++){
		bool ok = false;
		for(auto c:mp){
			if(c.se>=1&&a[i]+c.fi<n){
				ans+=a[i]+c.fi;
				mp[c.fi]--;
				if(mp[c.fi]==0) mp.erase(c.fi);
				ok = true;
				break;
			}
		}
		if(!ok){
			for(auto c:mp){
				ans+=(a[i]+c.fi)%n;
				mp[c.fi]--;
				if(mp[c.fi]==0) mp.erase(c.fi);
				break;
			}
		}
	}
	cout<<ans<<endl;
}