题目链接:https://www.luogu.org/problemnew/show/P1058
参考博客链接:https://www.luogu.org/blog/ahzxp/solution-p1058
题目理解
要找出L, K和m, n的关系。这个其实是比较复杂的。对于L,我们可以画出边界位置,然后验证,而K是一个动态的,就很麻烦。。。不过可以在样例的基础上进行修改,可以观察出结果。
正如原博客所讲:
显而易见,我们应当从后往前,从下往上,从左往右进行摆放,这样可以处理好遮挡的问题,因为此题的观察视角是右上方(相对于积木而言),如果本题的观察视角改变,处理的顺序也需要改变。
实际上,就是应该先从看不见的部分开始处理。
应该学会复制单个图形的方法对图像进行处理。
代码
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;
public class Main {
static final char[][] Stick = { "..+---+".toCharArray(), "./ /|".toCharArray(), "+---+ |".toCharArray(),
"| | +".toCharArray(), "| |/.".toCharArray(), "+---+..".toCharArray() };
static final int maxm = 550;
static char[][] paint = new char[maxm][maxm];
public static PrintWriter pw;
static int M, N;
static int L, K;
static final int maxn = 60;
static int[][] a = new int[maxn][maxn];
public static void main(String[] args) {
FastScanner fs = new FastScanner();
pw = new PrintWriter(new OutputStreamWriter(System.out));
N = fs.nextInt();
M = fs.nextInt();
// 画布宽度
L = 4 * M + 2 * N + 1;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
a[i][j] = fs.nextInt();
K = Math.max(K, a[i][j] * 3 + 2 * (N - i + 1) + 1);
}
}
for (int i = 1; i <= K; i++) {
for (int j = 1; j <= L; j++) {
paint[i][j] = '.';
}
}
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
int x = K - 2 * (N - i);
int y = 2 * (N - i) + 4 * (j - 1) + 1;
draw(x, y, a[i][j]);
}
}
for (int i = 1; i <= K; i++) {
for (int j = 1; j <= L; j++) {
pw.print(paint[i][j]);
}
pw.println();
}
pw.close();
}
public static void draw(int x, int y) {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
if (Stick[6 - i - 1][j] != '.') {
paint[x - i][y + j] = Stick[6 - i - 1][j];
}
}
}
}
public static void draw(int x, int y, int t) {
// 此处顺序是必须要从下
while (t-- > 0) {
draw(x, y);
x -= 3;
}
}
public static class FastScanner {
private BufferedReader br;
private StringTokenizer st;
public void eat(String s) {
st = new StringTokenizer(s);
}
public FastScanner() {
br = new BufferedReader(new InputStreamReader(System.in));
eat("");
}
public String nextLine() {
try {
return br.readLine();
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
public boolean hasNext() {
while (!st.hasMoreElements()) {
String s = nextLine();
if (s == null) {
return false;
}
eat(s);
}
return true;
}
public String nextToken() {
hasNext();
return st.nextToken();
}
public int nextInt() {
return Integer.valueOf(nextToken());
}
}
}