*,调了1.5d
2024-07-08 20:54:01
发布于:浙江
2阅读
0回复
0点赞
#include <bits/stdc++.h>
using namespace std;
int n,m;
int dx[4] = {0,0,-1,1};//x轴4个移动方向
int dy[4] = {1,-1,0,0};//y轴4个移动方向
bool g[110][110];//是否开灯
bool used[110][110];//标记是否处理过
bool tp[110][110];//标记是否可以在后面再次处理
struct node{//单个节点
int x,y;
};
struct light{
vector <node> a;//长度不变数组,用于存储长度不变的开关数量以及能打开的点
}l[110][110];
void dfs(int x,int y){
if(x < 1 || x > n || y < 1 || y > n) return; //越界判定
if(g[x][y] == 0){ //如果没有开灯,被标记后面处理
tp[x][y] = 1;
return;
}
if(used[x][y]) return;//如果已经出现过,则没必要处理
used[x][y] = 1;//标记
for(int i = 0;i < int(l[x][y].a.size());i++){//i 循环 vector中的每一个开关
g[l[x][y].a[i].x][l[x][y].a[i].y] = 1;//打开对应的灯
if(tp[l[x][y].a[i].x][l[x][y].a[i].y] && !used[l[x][y].a[i].x][l[x][y].a[i].y]) {//之前标记过的这次被打开
dfs(l[x][y].a[i].x,l[x][y].a[i].y); //临时DFS(传送过去)
}
tp[l[x][y].a[i].x][l[x][y].a[i].y] = 0;//结束它的标记
}
for(int i = 0;i < 4;i++){
int vx,vy;
vx = x,vy = y;//新的坐标
vx += dx[i],vy += dy[i];
dfs(vx,vy);//递归
}
return;
}
signed main(){
memset(used,0,sizeof(used));
ios::sync_with_stdio(0);//解绑cin cout
cin.tie(0);cout.tie(0);//读入输出优化
cin >> n >> m;
for(int i = 1;i <= m;i++){
int x,y,a,b;
cin >> x >> y >> a >> b;
l[x][y].a.push_back(node{a,b});//将对应位置的vector中加入当前这个开关
}
g[1][1] = 1;//1,1默认打开(那不然呢)
dfs(1,1);//开始递归
int cnt = 0;//统计开灯数量
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
if(g[i][j]) cnt++;//只需要判定当前有没有开灯
}
}
cout << cnt;
return 0;
}
这里空空如也
有帮助,赞一个