• 2020牛客寒假算法基础集训营3 【B】-牛牛的DRB迷宫II


    题目链接:https://ac.nowcoder.com/acm/contest/3004/B

    第一次写这种构造题,比赛的时候没想出来QAQ。构造方法很巧妙。先把官方题解的图拉过来。

    解释一下这张图:初始状态如图,空白区域(除了最后一行)全填D,最后一行全填R。

    从0开始计数,第i行第i列(即对角线元素)的值为2i(也就是1<<i)。2n之内的所有2的倍数通过各种组合的相加可以构成1到2n+1之间的所有数字。为便于理解对上图修改如下

    要求res对应的方格为最终答案,只需要判定res是由哪些数字构成的和,然后将对应列的蓝色区域的R改为B即可。这样就会将当前列对应的值向下传递直到最后一行。

    然后既然答案会对1e9+7取模,所以我们只需要计算30列,因为1<<30=1 073 741 824,下标0~29。

    对于行数而言需要32行,因为第31行(下标30)需要对第30行(下标29)的数据进行选择是否处理。第32行(下标31)全R来将答案从左到右传递到最后一格。

    对于判断由哪些数字组成的和利用二进制和位运算即可。

    附代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=55;
     4 char res[maxn][maxn];
     5 int main(){
     6     int n=32,m=30;
     7     int k;
     8     cin>>k;
     9     for(int i=0;i<30;i++){
    10         res[0][i]='D';
    11         res[30][i]='D';
    12         res[31][i]='R';
    13     }
    14     res[0][0]='B';
    15     res[30][29]='R';
    16     for(int i=1;i<30;i++){
    17         for(int j=0;j<i-1;j++){
    18             res[i][j]='D';
    19         }
    20         res[i][i-1]='R';
    21         res[i][i]='B';
    22         for(int j=i+1;j<30;j++){
    23             res[i][j]='D';
    24         }
    25     }
    26     for(int i=0;i<30;i++){
    27         if(k&(1<<i))res[i+1][i]='B';
    28     }
    29     cout<<n<<" "<<m<<"
    ";
    30     for(int i=0;i<n;i++){
    31         for(int j=0;j<m;j++){
    32             cout<<res[i][j];
    33         }
    34         cout<<"
    ";
    35     }
    36     return 0;
    37 }
  • 相关阅读:
    剑指Offer——翻转单词顺序列
    剑指Offer——左旋转字符串
    剑指Offer——和为S的两个数字
    剑指Offer——和为S的连续正数序列
    剑指Offer——数组中只出现一次的数字
    log4cxx入门第一篇--一个小例子
    gsoap写一个c++ webservice
    Protocol Buffer技术详解(数据编码)
    Protocol Buffer技术详解(Java实例)
    Protocol Buffer技术详解(C++实例)
  • 原文地址:https://www.cnblogs.com/charles1999/p/12288606.html
Copyright © 2020-2023  润新知