比赛地址: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; }