zoukankan      html  css  js  c++  java
  • 洛谷P2845-Switching on the Lights 开关灯

    Problem 洛谷P2845-Switching on the Lights 开关灯

    Accept: 154    Submit: 499
    Time Limit: 1000 mSec    Memory Limit : 128MB

    Problem Description

    Farm John 最近新建了一批巨大的牛棚。这些牛棚构成了一个N*N的矩形网络。(1<n<100)

    然而bessie十分怕黑,他想计算可以把多少个牛棚的灯打开。

    有N*N个房间,组成了一张N*N的网格图,Bessie一开始位于左上角(1,1),并且只能上下左右行走。

    一开始,只有(1,1)这个房间的灯是亮着的,Bessie只能在亮着灯的房间里活动。

    有另外M条信息,每条信息包含四个数a,b,c,d,表示房间(a,b)里有房间(c,d)的灯的开关。

    请计算出最多有多少个房间的灯可以被打开。

     Input

    第一行,两个数:N,M(1<m<200000);

    第2-m+1行:坐标(x1,y1),(x2,y2)代表房间的坐标(x1,y1)及可以点亮的·房间的坐标(x2,y2);

     Output

    一个数,最多可以点亮的房间数

     

     Sample Input

    3 6
    1 1 1 2
    2 1 2 2
    1 1 1 3
    2 3 3 1
    1 3 1 2
    1 3 2 1

     Sample Output

    5

    题目链接:https://www.luogu.org/problemnew/show/P2845

    题解:乍一看这个题觉得这个题咋这么水,凉了之后画了个稍微大一点图,意识到用普通的广搜的话,会有一些点会被误判为不能到的点而只是点亮而不进队,这样就很明显有问题了。

    解决方案其实挺好想的,把原来的vis数组变成vis和illu数组,前者用来标记到过没有,后者标记点亮没有,新到一个房间,有一些它能打开的灯,对于这些点,判断它的四周有没有之前到过的点,

    如果有,那它也能到,入队。当然了,判断当前房间四周有没有开灯是必然的。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <cstdio>
      5 #include <queue>
      6 using namespace std;
      7 
      8 const int maxn = 100+10,maxm = 200000+10;
      9 
     10 bool vis[maxn][maxn];
     11 bool illu[maxn][maxn];
     12 int n,m;
     13 int tot,head[maxn*maxn];
     14 int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
     15 
     16 struct Point{
     17     int x,y;
     18     Point(int x = 0,int y = 0) :
     19         x(x),y(y) {}
     20 };
     21 
     22 struct Edge{
     23     int to,next;
     24     Edge(int to = 0,int next = 0) :
     25         to(to),next(next) {}
     26 }edge[maxm];
     27 
     28 void AddEdge(int u,int v){
     29     edge[tot].to = v;
     30     edge[tot].next = head[u];
     31     head[u] = tot++;
     32 };
     33 
     34 inline void cal(int v,int &x,int &y){
     35     if(v%n == 0){
     36         x = v/n,y = n;
     37     }
     38     else x = v/n+1,y = v%n;
     39 }
     40 
     41 inline bool Judge(int x,int y){
     42     if(1<=x && 1<=y && x<=n && y<=n) return true;
     43     return false;
     44 }
     45 
     46 void BFS(){
     47     queue<Point> que;
     48     que.push(Point(1,1));
     49     vis[1][1] = illu[1][1] = true;
     50     while(!que.empty()){
     51         Point first = que.front();
     52         que.pop();
     53         int u = (first.x-1)*n+first.y;
     54         for(int k = 0;k < 4;k++){
     55             int xx = first.x+dir[k][0],yy = first.y+dir[k][1];
     56             if(Judge(xx,yy)){
     57                 if(!vis[xx][yy] && illu[xx][yy]){
     58                     vis[xx][yy] = true;
     59                     que.push(Point(xx,yy));
     60                 }
     61             }
     62         }
     63         for(int i = head[u];i != -1;i = edge[i].next){
     64             int v = edge[i].to;
     65             int x,y;
     66             cal(v,x,y);
     67             illu[x][y] = true;
     68             if(!vis[x][y]){
     69                 for(int k = 0;k < 4;k++){
     70                     int xx = x+dir[k][0],yy = y+dir[k][1];
     71                     if(Judge(xx,yy) && vis[xx][yy]){
     72                         vis[x][y] = true;
     73                         que.push(Point(x,y));
     74                     }
     75                 }
     76             }
     77         }
     78     }
     79 }
     80 
     81 int main()
     82 {
     83     //freopen("input.txt","r",stdin);
     84     memset(vis,false,sizeof(vis));
     85     memset(illu,false,sizeof(illu));
     86     memset(head,-1,sizeof(head));
     87     tot = 1;
     88     scanf("%d%d",&n,&m);
     89     int a,b,c,d;
     90     for(int i = 1;i <= m;i++){
     91         scanf("%d%d%d%d",&a,&b,&c,&d);
     92         int u = (a-1)*n+b,v = (c-1)*n+d;
     93         AddEdge(u,v);
     94     }
     95     BFS();
     96     int ans = 0;
     97     for(int i = 1;i <= n;i++){
     98         for(int j = 1;j <= n;j++){
     99             if(illu[i][j]) ans++;
    100         }
    101     }
    102     printf("%d
    ",ans);
    103     return 0;
    104 }
  • 相关阅读:
    从国内流程管理软件市场份额看中国BPM行业发展
    为什么流程是成功企业的关键?
    港真,到底应该选择OA还是BPM?
    hello world
    i40e网卡驱动遇到的一个问题
    suse 11 sp3编译报错问题
    linux scsi相关的一些学习笔记
    linux tcp 在timewait 状态下的报文处理
    趋势科技 redirfs模块的一个小问题
    linux 3.10 一个扇区异常可能引发的hung
  • 原文地址:https://www.cnblogs.com/npugen/p/9496048.html
Copyright © 2011-2022 走看看