LA 7747 Appearance Analysis——模拟

xiaoxiao2021-02-28  121

题意:给定一个大窗户(严格按照规则给出),窗户上有很多种玻璃,相同玻璃可以通过旋转而得,问一共有多少种玻璃

思路:存下每块玻璃的左上角坐标,配合玻璃的尺寸来表示每块玻璃,然后遍历即可求解,坐标的旋转规则:(i,j)(j,m-i+1)(m-i+1,n-j+1)(n-j+1,i)

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 120; int m, n, x, y, cnt, ans, vis[maxn * maxn]; char str[maxn][maxn]; struct Window { int x, y; }window[maxn * maxn]; void init() { cnt = ans = 0; memset(vis, 0, sizeof(vis)); } int main() { while (scanf("%d %d", &m, &n) == 2) { getchar(); init(); for (int i = 1; i <= m; i++) gets(str[i] + 1); for (int i = 2; i <= m; i++) if (str[i][2] == '#') { x = i - 2; break; } for (int i = 2; i <= n; i++) if (str[2][i] == '#') { y = i - 2; break; } for (int i = 2; i <= m; i += (x + 1)) { for (int j = 2; j <= n; j += (y + 1)) { window[++cnt].x = i, window[cnt].y = j; } } for (int w1 = 1; w1 <= cnt; w1++) { if (vis[w1]) continue; vis[w1] = 1, ans++; for (int w2 = w1 + 1; w2 <= cnt; w2++) { if (vis[w2]) continue; bool ok1 = true, ok2 = true, ok3 = true, ok4 = true; if (x == y) { for (int i = 1; i <= x; i++) { for (int j = 1; j <= y; j++) { int x1 = window[w1].x + i - 1, y1 = window[w1].y + j - 1, x2 = window[w2].x + i - 1, y2 = window[w2].y + j - 1; if (str[x1][y1] != str[x2][y2]) ok1 = false; if (str[x1][y1] != str[x-i+window[w2].x][y-j+window[w2].y]) ok2 = false; if (str[x1][y1] != str[j+window[w2].x-1][x-i+window[w2].y]) ok3 = false; if (str[x1][y1] != str[y-j+window[w2].x][i+window[w2].y-1]) ok4 = false; } } if (ok1 || ok2 || ok3 || ok4) vis[w2] = 1; } else { for (int i = 1; i <= x; i++) { for (int j = 1; j <= y; j++) { int x1 = window[w1].x + i - 1, y1 = window[w1].y + j - 1, x2 = window[w2].x + i - 1, y2 = window[w2].y + j - 1; if (str[x1][y1] != str[x2][y2]) ok1 = false; if (str[x1][y1] != str[x-i+window[w2].x][y-j+window[w2].y]) ok2 = false; } } if (ok1 || ok2) vis[w2] = 1; } } } printf("%d\n", ans); } }

转载请注明原文地址: https://www.6miu.com/read-19415.html

最新回复(0)