[ABC219E] Moat 题解
1.AT_abc333_e [ABC333E] Takahashi Quest 题解2.[ABC265F] Manhattan Cafe 题解3.[ABC271E] Subsequence Path 题解4.[ABC273D] LRUD Instructions 题解5.P8085 [COCI2011-2012#4] KRIPTOGRAM 题解6.[ABC238F] Two Exams 题解7.[ABC217F] Make Pair 题解8.[ABC219F] Cleaning Robot 题解
9.[ABC219E] Moat 题解
10.[ABC221D] Online games 题解11.[ABC221E] LEQ 题解12.[ABC223E] Placing Rectangles 题解13.[ABC211D] Number of Shortest paths 题解14.[ABC211F] Rectilinear Polygons 题解15.[ABC223F] Parenthesis Checking 题解16.CF154C Double Profiles 题解17.[ABC208D] Shortest Path Queries 2 题解18.[ABC212E] Safety Journey 题解19.[ABC229E] Graph Destruction 题解20.[ABC240E] Ranges on Tree 题解21.[ABC261E] Many Operations 题解22.P10842 【MX-J2-T3】Piggy and Trees 题解[ABC219E] Moat 题解
思路解析
一眼看到输入数据只有
其中蓝线表示护城河,绿色阴影表示护城河包围的格子。可见图中有两条护城河,不符合题意。为排除掉这种情况,我们判断每一个没有被选择的格子,判断它是否被护城河完全包围,也就是判断能否走到地图外即可。
时间复杂度:首先一次暴力枚举,然后对于每种情况需要判断是否为可行方案,洪水填充最多遍历
code
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define fir first
#define sec second
int v[8][8], flag[8][8], f[8][8], ans = 0;
bool vis[8][8];
int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};
void flood(int x, int y) {
queue< PII > q;
q.push({x, y});
while(!q.empty()) {
int xx = q.front().fir, yy = q.front().sec;
q.pop();
for(int i = 0; i < 4; i++) {
int nx = xx + dx[i], ny = yy + dy[i];
if(flag[nx][ny] && !f[nx][ny]) {
f[nx][ny] = true;
q.push({nx, ny});
}
}
}
}
bool flood_loop(int x, int y) {
queue< PII > q;
q.push({x, y});
memset(vis, false, sizeof(vis));
vis[x][y] = true;
while(!q.empty()) {
int xx = q.front().fir, yy = q.front().sec;
q.pop();
for(int i = 0; i < 4; i++) {
int nx = xx + dx[i], ny = yy + dy[i];
if(!flag[nx][ny] && !vis[nx][ny]) {
if(nx >= 1 && nx <= 4 && ny >= 1 && ny <= 4) {
vis[nx][ny] = true;
q.push({nx, ny});
}
else return true;
}
}
}
return false;
}
int check() {
int x = 0, y = 0, cnt = 0;
for(int i = 1; i <= 4; i++) {
for(int j = 1; j <= 4; j++) {
if(flag[i][j]) cnt++, x = i, y = j;
}
}
memset(f, 0, sizeof(f));
f[x][y] = 1;
flood(x, y); //洪水填充判断连通
int sum = 0;
for(int i = 1; i <= 4; i++) {
for(int j = 1; j <= 4; j++) {
if(f[i][j]) sum++;
}
}
if(sum != cnt) return 0; //不连通
for(int i = 1; i <= 4; i++) {
for(int j = 1; j <= 4; j++) {
if(v[i][j] && !f[i][j]) return 0; //若有村庄没被包含
}
}
for(int i = 1; i <= 4; i++) {
for(int j = 1; j <= 4; j++) {
if(!flag[i][j] && !flood_loop(i, j)) return 0; //被护城河完全包围
}
}
return 1;
}
void dfs(int x, int y) { //暴力枚举
if(y > 4) y = 1, x++;
if(x > 4) {
ans += check();
return;
}
flag[x][y] = 1;
dfs(x, y + 1);
flag[x][y] = 0;
dfs(x, y + 1);
}
int main() {
for(int i = 1; i <= 4; i++) {
for(int j = 1; j <= 4; j++) {
cin >> v[i][j];
}
}
dfs(1, 1);
cout << ans;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】