这一次的排位赛比较简单,所以只挑了 7-8 和 7-12
7-8
2014 年哈佛-麻省理工数学竞赛中一道题是这样的:将正整数 1, 2, ..., 64 填入 8×8 的方格棋盘中,使得对任何 1≤i<64,i 和 i+1 都必须填在两个具有公共边的方格中。求棋盘上对角线中所填数的和的最大值。(注意:两个对角线都要考虑;64 和1 也必须填在两个具有公共边的方格中。)
这题有点难…… 幸好我们并不要求你写程序解决这个问题。
你的任务是:对任一给定的数字填充方案,判定其是否满足填充的条件,并且在所有给出的方案中,找出满足条件的、且对角线数字和最大的那个方案。
\(\qquad\) 对于这一道题,我们可以选择用模拟的方式,只需要枚举每一个 i 的上下左右四个偏移量看是否存在 i+1 即可,值得注意的是,对于 n*n 我们需要寻找的是四个偏移量中是否存在 1.
\(\qquad\) 然后就是这道题最大的一个毒点,测试点 2,19分的应该基本上都是WA在这里了。这一个测试点的要求为,当不存在符合要求的矩阵时,不仅要输出0,还要输出两个换行。
#include <bits/stdc++.h>using namespace std;#define pii pair<int, int>
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};int main(){int n, m;cin >> n >> m;priority_queue<pii> q;//bool vis[n+1][n+1];vector<vector<int>> g(n+1, vector<int>(n+1));int cnt = 0;while(m--){cnt++;//memset(vis, 0, sizeof(vis));for(int i = 1; i <= n; i ++ ){for(int j = 1; j <= n; j ++ ){cin >> g[i][j];}}bool fg = 1;for(int i = 1; i <= n; i ++ ){for(int j = 1; j <= n; j ++ ){int s = 0;// if(g[i][j] == n*n) continue;// for(int k = 0; k < 4; k ++ ){// int nx = i + dx[k], ny = j + dy[k];// if(nx < 1 || nx > n || ny < 1 || ny > n) continue;// if(g[nx][ny] == g[i][j] + 1) s++;// }if(g[i][j] == n*n){for(int k = 0; k < 4; k ++ ){int nx = i + dx[k], ny = j + dy[k];if(nx < 1 || nx > n || ny < 1 || ny > n) continue;if(g[nx][ny] == 1) s++;}} else {for(int k = 0; k < 4; k ++ ){int nx = i + dx[k], ny = j + dy[k];if(nx < 1 || nx > n || ny < 1 || ny > n) continue;if(g[nx][ny] == g[i][j] + 1) s++;}}if(!s) fg = 0;}}if(!fg) continue;int ans1 = 0, ans2 = 0;for(int i = 1; i <= n; i ++ ) ans1 += g[i][i];for(int i = n, j = 1; i >= 1; i -- , j ++ ) ans2 += g[j][i];int ans = max(ans1, ans2);q.push({ans, cnt});}// while(q.size()){// auto t = q.top();q.pop();// cout << t.second << ' ';// }// cout << q.size() << endl;if(q.empty()){cout << 0 << endl; cout << endl; return 0;} //没有符合要求的要输出两个换行int maxx = q.top().first;int ans = 0;vector<int> res;while(q.size() && q.top().first == maxx){ans ++;auto t = q.top(); q.pop();res.push_back(t.second);}cout << ans << endl;sort(res.begin(), res.end());for(int i = 0; i < res.size(); i ++ ){if(i == 0) cout << res[i];else cout << ' ' << res[i];}
}