题目大意:n*n的网格,每个网格是一个房间
都关着灯,只有(1,1)开着灯,且(x,y)有着(z,k)房间灯的开关。
问从(1,1)开始走最多点开几盏灯。
题解:搜索+骗分。
劳资的骗分天下无敌,劳资的骗分世界第一
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<vector> #define N 102 using namespace std; int n,m,ans=1,js; int vis[N][N],b[N][N],ok[N][N]; int mx[4]={0,1,-1,0}, my[4]={1,0,0,-1}; struct node{ int x,y; }; struct T{ int x,y; }; queue<T>q; vector<node>a[N][N]; void bfs(){ T c;c.x=1;c.y=1;q.push(c); vis[1][1]=true;b[1][1]=true; while(!q.empty()){ T now=q.front();q.pop();js++; if(js==n*n*100)return; //遍历了这么多遍应该灯应该都开了吧。 int xx=now.x,yy=now.y; for(int i=0;i<a[xx][yy].size();i++){ node g=a[xx][yy][i]; if(b[g.x][g.y]==0)ans++; b[g.x][g.y]=true; } for(int i=0;i<4;i++){ int nx=xx+mx[i],ny=yy+my[i]; if(nx<1||nx>n||ny<1||ny>n||vis[nx][ny]||b[nx][ny]==0) continue; vis[nx][ny]=true; T tmp;tmp.x=nx;tmp.y=ny; q.push(tmp); } q.push(now); } } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int x,y,nx,ny; scanf("%d%d%d%d",&x,&y,&nx,&ny); node t;t.x=nx;t.y=ny; a[x][y].push_back(t); } bfs(); printf("%d ",ans); return 0; }
骗分归骗分正解还是要学的
每点开一盏灯,看这盏灯的上下左右是否被点开灯了
有被点开的就开始搜这个点。