Logo xushuoxin的博客

博客

#865 题解

2023-03-24 22:42:46 By xushuoxin
前话:
zuotingting
865把你的答案写个题解给大家看下。
发送时间:2023-03-24 09:27:58
查看时间:2023-03-24 16:57:06
老师要求我写的啊,新思路看不懂不背锅(都这么详细了,我尽力了)……

题目链接

首先理解题意,根据样例,知道$2^n$就是这个图腾的行数.

仔细数一下每行的前导空格个数,发现是总行数-当前行数.

接着,重点来了,由于这个图腾构造有序,大致可以如下表示,保存在布尔型数组里.

大小为1  大小为2   大小为3
   1       1         1
  1 1     1 1       1 1
         1 0 1     1 0 1
        1 1 1 1   1 1 1 1
                 1 0 0 0 1
                1 1 0 0 1 1
               1 0 1 0 1 0 1
              1 1 1 1 1 1 1 1

如上,一个0就表示两个空格,奇数行的一个1表示"/\",偶数行的两个1表示"/__\".

那怎样用布尔数组得到大体的图腾呢?很简单,以大小是2的图腾为例,

首先,我们得把数组全赋成0,然后,把它第一行唯一一个1,根据数组位置(1,1)保存进去.

(小提示:数组外面多包一层0,不然会越界.)

初始数组:
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

然后,从第二行开始,偶数行挨列判断上面一行的这个位置与上面一行的前一个位置是否都是0(没有三角形的尖).

奇数行挨列判断上面一行的这个位置与上面一行的前一个位置是否都是1(新的三角形要么在上面一个三角形的左边,要么在右边,不能在中间).

如果判断为否,则这个位置可以补全(新增)一个小三角形,数组保存为1,否则为0(空格).

总的来说,就是保存上面一行的这个位置与上面一行的前一个位置的异或运算的结果.

实践一下.

第一次修改.
0 0 0 0 0
0 1 0 0 0
0 1 1 0 0
0 0 0 0 0
0 0 0 0 0
第二次修改.
0 0 0 0 0
0 1 0 0 0
0 1 1 0 0
0 1 0 1 0
0 0 0 0 0
第三次修改.
0 0 0 0 0
0 1 0 0 0
0 1 1 0 0
0 1 0 1 0
0 1 1 1 1
Over!

布尔数组转成图腾见上文,不说了.

还有一点,"\"在c++中不能直接输出,要写成(char)(92).

上AC代码!(可能有些细节跟上面思路不一样,但大体相同,也是正确的).

#include<bits/stdc++.h>
using namespace std;
int n,h,a[3005][3005];
void output(string s){
    cout<<s<<(char)(92);
    return;
}
int main(){
    cin>>n;a[0][0]=1,h=pow(2,n);
    for(int i=1;i<=h;i++){
        for(int j=i;j<h;j++)
            cout<<" ";
        for(int j=1;j<=i;j++)
            a[i][j]=(a[i-1][j]+a[i-1][j-1])%2;
        for(int j=1;j<=i;j++){
            if(i%2!=0){
                if(a[i][j])
                    output("/");
                else
                    cout<<"  ";                
            }
            else{
                if(a[i][j]&&a[i][++j])
                    output("/__");
                else
                    cout<<"   ";            
            }
        }
        cout<<endl;
    }
    return 0;
}

评论

阿兹卡班的小天狼星
这题是分冶吗

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。