题目链接:Marlin
题意
在一个 4×n 4 × n ( n n 为奇数)的网格中,需要设置 个障碍,这 k k 个障碍不能设置在网格的边界上,要求从 到达 (4,n) ( 4 , n ) 的最短路径数量等于从 (4,1) ( 4 , 1 ) 到 (1,n) ( 1 , n ) 的最短路径数量,两个方格之间的路径长度为 1 1 ,当且仅当这两个方格有公共边。
输入
输入只包含两个整数 ,数据保证 n n 为奇数。
输出
如果可以达到要求,第一行输出 ,接下去 4 4 行每行 个字符,字符只能包含
.
和#
,其中.
表示空地,#
表示障碍物。
样例
输入 |
---|
7 2 |
输出 |
YES....... .#..... .#..... ....... |
输入 |
---|
5 3 |
输出 |
YES..... .###. ..... ..... |
题解
对于 k k 为偶数的情况,只需要上下对称分布,对于奇数的情况,以下枚举了 时, k k 等于 的构造方案:
.....
.....
.....
..#..
.###.
.###.
.....
.....
.#.#.
.....
.....
.....
不存在无法构造的情况。
过题代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <algorithm>
using namespace std;
#define LL long long
const int maxn = 100 + 100;
int n, k;
char ans[maxn][maxn];
int main() {
#ifdef LOCAL
freopen("test.txt", "r", stdin);
// freopen("testout.txt", "w", stdout);
#endif // LOCAL
ios::sync_with_stdio(false);
while(scanf("%d%d", &n, &k) != EOF) {
for(int i = 1; i <= 4; ++i) {
for(int j = 1; j <= n; ++j) {
ans[i][j] = '.';
}
}
if(k % 2 == 0) {
for(int j = 2; j < k / 2 + 2; ++j) {
for(int i = 2; i <= 3; ++i) {
ans[i][j] = '#';
}
}
} else {
int up = min(n - 2, k);
int mid = n / 2 + 1;
for(int i = 0; i <= up / 2; ++i) {
ans[2][mid + i] = '#';
ans[2][mid - i] = '#';
}
up = max(k - (n - 2), 0);
for(int i = 0; i < up / 2; ++i) {
ans[3][2 + i] = '#';
ans[3][n - 1 - i] = '#';
}
}
printf("YES\n");
for(int i = 1; i <= 4; ++i) {
for(int j = 1; j <= n; ++j) {
printf("%c", ans[i][j]);
}
printf("\n");
}
}
return 0;
}