zoukankan      html  css  js  c++  java
  • 2019 Multi-University Training Contest 10 I Block Breaker

    Problem Description

    Given a rectangle frame of size n×m. Initially, the frame is strewn with n×m square blocks of size 1×1. Due to the friction with the frame and each other, the blocks are stable and will not drop.

    However, the blocks can be knocked down. When a block is knocked down, other remaining blocks may also drop since the friction provided by other remaining blocks may not sustain them anymore. Formally, a block will drop if it is knocked or not stable, which means that at least one of the left block and the right block has been dropped and at least one of the front block and the back block has been dropped. Especially, the frame can be regarded as a huge stable block, which means that if one block's left is the frame, only when its right block has been dropped and at least one of the front block and the back block has been dropped can it drop. The rest situations are similar.

    Now you, the block breaker, want to knock down the blocks. Formally, you will do it q times. In each time, you may choose a position (xi,yi). If there remains a block at the chosen position, you will knock it down; otherwise, nothing will happen. Moreover, after knocking down the block, you will wait until no unstable blocks are going to drop and then do the next operation.

    For example, please look at the following illustration, the frame is of size 2×2 and the block (1,1) and (1,2) have been dropped. If we are going to knock the block (2,2), not only itself but also the block (2,1) will drop in this knocking operation.
     

    You want to know how many blocks will drop in total in each knocking operation. Specifically, if nothing happens in one operation, the answer should be regarded as 0.

    Input

    The first line contains one positive integer T (1≤T≤10), denoting the number of test cases.
    For each test case:
    The first line contains three positive integers n,m and q (1≤n,m≤2000,1≤q≤100000), denoting the sizes in two dimensions of the frame and the number of knocking operations.
    Each of the following q lines contains two positive integers xi and yi (1≤xi≤n,1≤yi≤m), describing a knocking operation.

    Output

    For each test case, output q lines, each of which contains a non-negative integer, denoting the number of dropped blocks in the corresponding knocking operation.

    Sample Input

    2 2 2 3 1 1 1 2 2 2 4 4 6 1 1 1 2 2 1 2 2 4 4 3 3
    Sample Output
    1 1 2 1 1 2 0 1 11

    非常基础深度搜题,有点生。直接写的,死活都是WA,过了过了这个题。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define maxx 2010
    int n,m;
    int net[4][2]={0,1,1,0,-1,0,0,-1};//这里千万不要用next[];
    struct node{
        int s;//记录此位置是否还有方块
        int q,d,l,r;//记录方块的上下左右是否还有方块
    }a[maxx][maxx];
    int dfs(int x,int y){   //进行深搜看是否还有满足掉落的方块
        int sum=0;
        for(int i=0;i<4;i++){
            int tx=x+net[i][0];
            int ty=y+net[i][1];
            if(tx<=0||ty<=0||tx>n||ty>m||!a[tx][ty].s)
               continue;
            if((!a[tx][ty].q||!a[tx][ty].d)&&(!a[tx][ty].l||!a[tx][ty].r)){//不稳定方块的判断条件,上面有介绍;
                sum++;
              a[tx][ty].s=0;    
              a[tx+1][ty].l=0;
              a[tx-1][ty].r=0;
              a[tx][ty+1].d=0;
              a[tx][ty-1].q=0;
              sum+=dfs(tx,ty);
            }
        }
        return sum;
    }
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            int q;
            scanf("%d%d%d",&n,&m,&q);
            for(int i=0;i<=n+1;i++)//为啥从“0”到“n+1”和“0”到“m+1”
            for(int j=0;j<=m+1;j++){//因为矩阵的四条边都是有摩擦的
             a[i][j].s=1,a[i][j].d=1,a[i][j].l=1;
             a[i][j].r=1,a[i][j].q=1;
            }
            int x,y;
            for(int i=1;i<=q;i++){
              int sum=0;//记录掉的个数
              scanf("%d%d",&x,&y);  
              if(a[x][y].s){
                   sum++;
                   //把与此位置有关联的方块所对应的位置标记为“0”
              a[x][y-1].q=0;//“下”方块的上标记为0;
              a[x+1][y].l=0;//同理右面的左标记为0;
              a[x-1][y].r=0;//左的右为0
              a[x][y+1].d=0;//上的下为0;
              a[x][y].s=0;//掉落将其标记为0
              sum+=dfs(x,y);
              }
              printf("%d
    ",sum);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    EzHttp 流传输调用代码示例
    使用EzHttp框架 开发基于HTTP协议的CS轻应用
    [转]Installing Memcached on Windows
    SQLiteServer+SQLiteClient 用于.Net项目的SQLite服务端程序和客户端类库
    ERROR: Pillow-5.2.0-cp35-cp35m-win_amd64.whl is not a supported wheel on this platform.
    Linux下的tar压缩解压缩命令详解
    scp 基于 SSH 的安全远程服务器文件拷贝
    大批量删除列表中元素的方法,自己用本办法做的
    Python 列表 pop() 方法
    可遍历的数据对象enumerate() 方法的使用
  • 原文地址:https://www.cnblogs.com/lunatic-talent/p/12798601.html
Copyright © 2011-2022 走看看