Codeforces#566 B. Plus from Picture(思維)
阿新 • • 發佈:2020-08-12
剛看到一個做法很棒,列舉十字中點然後向四周擴充套件“十字”,並計數,如果數量等於*
總數就輸出YES,否則輸出NO.
暴力程式碼:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<map> #include<queue> #include<vector> #include<string> #include<fstream> using namespace std; #define rep(i, a, n) for(int i = a; i <= n; ++ i); #define per(i, a, n) for(int i = n; i >= a; -- i); typedef long long ll; const int N = 600; const int mod = 998244353; const double Pi = acos(- 1.0); const ll INF = 1e9; const int G = 3, Gi = 332748118; ll qpow(ll a, ll b) { ll res = 1; while(b){ if(b & 1) res = (res * a) % mod; a = (a * a) % mod; b >>= 1;} return res; } ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; } // int n, m; char s[N]; int a[N][N]; int dp[N][N][5]; int vis[N][N]; bool check(int x, int y, int flag, int to){ if(x < 1 || x > n || y < 1 || y > m || !a[x][y]) return false; int val = 0; if(!flag){ for(int i = 0; i < 4; ++ i){ val += (dp[x][y][i] > 1) ? 1 : 0; } if(val == 4 && a[x][y]) return true; } vis[x][y] = 1; bool tpp = false; if(to == 0){ if(a[x - 1][y] && !vis[x - 1][y]){ if(check(x - 1, y, 0, to)) tpp = true; } if(a[x + 1][y] && !vis[x + 1][y]){ if(check(x + 1, y, 0, to)) tpp = true; } } else{ if(a[x][y - 1] && !vis[x][y - 1]){ if(check(x, y - 1, 0, to)) tpp = true; } if(a[x][y + 1] && !vis[x][y + 1]){ if(check(x, y + 1, 0, to)) tpp = true; } } return tpp; } void solve(){ for(int i = 1; i <= n; ++ i){ for(int j = 1; j <= m; ++ j){ if(!a[i][j]) continue; dp[i][j][0] = dp[i - 1][j][0] + 1; dp[i][j][1] = dp[i][j - 1][1] + 1; } } for(int i = n; i >= 1; -- i){ for(int j = m; j >= 1; -- j){ if(!a[i][j]) continue; dp[i][j][2] = dp[i + 1][j][2] + 1; dp[i][j][3] = dp[i][j + 1][3] + 1; } } int num = 0, flag = 0; for(int i = 1; i <= n; ++ i){ for(int j = 1; j <= m; ++ j){ if(!a[i][j]) continue; int tp = 0; if(dp[i][j][0] > 1) tp ++; if(dp[i][j][1] > 1) tp ++; if(dp[i][j][2] > 1) tp ++; if(dp[i][j][3] > 1) tp ++; if(tp == 4) num ++; else if(tp == 0 || tp == 3){ flag = 1; break; } else if(tp == 2){ if((a[i - 1][j] != a[i + 1][j]) || (a[i][j - 1] != a[i][j + 1])){ flag = 1; break; } memset(vis, 0, sizeof(vis)); if(a[i - 1][j]) check(i, j, 1, 0); else check(i, j, 1, 1); } else{ memset(vis, 0, sizeof(vis)); int to; if(a[i - 1][j] || a[i + 1][j]) to = 0; else to = 1; if(!check(i, j, 1, to)) { flag = 1; break; } } } if(flag) break; } if(!flag && num == 1) printf("YES\n"); else printf("NO\n"); } int main() { scanf("%d%d",&n,&m); for(int i = 1; i <= n; ++ i){ scanf("%s",s + 1); for(int j = 1; j <= m; ++ j){ a[i][j] = (s[j] == '*') ? 1 : 0; } } solve(); return 0; }