A. Shape Perimeter
题意:一个\(m \times m\)的印章每次往右上方向移动,问盖出来的图形周长。
假设每次都能盖\(m \times m\)的格子,那么看每两次盖章有多重复的减去就行。第\(i\)次移动了\(x_i, y_i\),那么就会有一个\(m-x_i, m-y_i\)的矩形被重复覆盖,减去它的周长。
点击查看代码
void solve() {int n, m;std::cin >> n >> m;std::vector<int> x(n), y(n);for (int i = 0; i < n; ++ i) {std::cin >> x[i] >> y[i];}i64 ans = m * 4 * n;for (int i = 1; i < n; ++ i) {ans -= (m - x[i] + m - y[i]) * 2;}std::cout << ans << "\n";
}
B. Find the Permutation
题意:有一个排列,给你一个矩阵表示\(y\)是否在\(x\)后面\((y>x)\), 求出这个排列。
对于每一对\(xy\),我们都可以知道谁在前面,前面的向后面连边,那么没入度的点就是第一个,依次推出其他点的位置。用拓扑排序即可。
点击查看代码
void solve() {int n;std::cin >> n;std::vector<std::string> s(n);for (int i = 0; i < n; ++ i) {std::cin >> s[i];}std::vector<std::vector<int> > adj(n);std::vector<int> in(n);for (int i = 0; i < n; ++ i) {for (int j = i + 1; j < n; ++ j) {if (s[i][j] == '1') {adj[i].push_back(j);++ in[j];} else {adj[j].push_back(i);++ in[i];}}}std::queue<int> q;std::vector<int> ans;for (int i = 0; i < n; ++ i) {if (in[i] == 0) {q.push(i);}}while (q.size()) {int u = q.front(); q.pop();ans.push_back(u);for (auto & v : adj[u]) {if ( -- in[v] == 0) {q.push(v);}}}for (auto & x : ans) {std::cout << x + 1 << " \n"[x == ans.back()];}
}
C. Palindromic Subsequences
题意:构造一个数组使得长度最长的最长回文子序列数量最多。
如果我们填\(1\)~\(n-3\),后面三个填1,2,3。你们发现会有\(3(n-4)\)个最长回文子序列。当\(n\)大于6的时候满足\(3(n-4) > n\)。\(n\)等于6我直接抄的样例。
点击查看代码
void solve() {int n;std::cin >> n;if (n == 6) {std::cout << 1 << " " << 1 << " " << 2 << " " << 3 << " " << 1 << " " << 2 << "\n";return;}int m = n - 3;for (int i = 1, x = 0; i <= n; ++ i) {std::cout << x + 1 << " \n"[i == n];x = (x + 1) % m;}
}
D. Unique Median
不会。坐了两个小时牢
待补