P1319 压缩技术

题目描述

设某汉字由 N \times N\texttt 0\texttt 1 的点阵图案组成。

我们依照以下规则生成压缩码。连续一组数值:从汉字点阵图案的第一行第一个符号开始计算,按书写顺序从左到右,由上至下。第一个数表示连续有几个 \texttt 0,第二个数表示接下来连续有几个 \texttt 1,第三个数再接下来连续有几个 \texttt 0,第四个数接着连续几个 \texttt 1,以此类推……

例如: 以下汉字点阵图案:

0001000
0001000
0001111
0001000
0001000
0001000
1111111

对应的压缩码是: \texttt {7 3 1 6 1 6 4 3 1 6 1 6 1 3 7} (第一个数是 N ,其余各位表示交替表示0和1 的个数,压缩码保证 N \times N= 交替的各位数之和)

输入格式

数据输入一行,由空格隔开的若干个整数,表示压缩码。

其中,压缩码的第一个数字就是 N,表示这个点阵应当是 N\times N 的大小。

接下来的若干个数字,含义如题目描述所述。

输出格式

输出一个 N\times N 的 01 矩阵,表示最后的汉字点阵图(点阵符号之间不留空格)。


问题分析

一般遇到这种奇怪的输出格式的时候,我们不需要纠结到底怎么用过程代码实现这个逆天的结构。我们可以这么联想——把答案缓存起来,然后再进行这沟槽的排版。这个思路是极其重要的,能减轻你大量不必要的过程构思。

这题很明显,输入格式中除去第一个数字,其它的就是交代了有多少个01。也就是说,它给你数字 n ,你就连续存储 n 个0或者1。按照这个思路,我们根本不需要构造什么二位数组,一个一维的数组就够了。

        for(int i=0; i<num; ++i)
        {
            matrix[sum+i]=stuck;    //连续存储num个0或1
        }

然后是输出格式。众所周知数组里肯定有 n \times n 个元素。可以设立一次循环,按行输出,遇到行末进行换行。

这样,这题的思路就这么简单地构想好了。


变量初始化

我们根据题意,只需构建一个 N\times N 的一维数组就行了。这里我虽然定义了一个大的数组,但实际用到的就那么多,所以无所谓。

bool matrix[114514]={0};

每一个输入的变量作为循环次数的限定,同时也作为总循环的边界判断,毕竟总数据只有 n \times n 个。

if(sum>=n*n) break; //循环边界判断
int num; std::cin>>num; //输入当前的数量
​
//...加入元素的循环
​
sum+=num;   //循环结束当前元素个数统计

然后,每次填充完毕,填入的数字要从0变为1或者1变为0。这里我用的是布尔型,所以直接取反。

stuck=!stuck;

代码

#include<iostream>
​
//P1319 压缩技术
int main(){
    int n; std::cin>>n;
    int sum=0;
    bool stuck=0;
    bool matrix[114514]={0};
​
    //开始正式输入与存储
    while(sum<=n*n)
    {
        if(sum>=n*n) break;
        int num; std::cin>>num;
​
        for(int i=0; i<num; ++i)
        {
            matrix[sum+i]=stuck;
        }
​
        sum+=num;
        stuck=!stuck;
    }
​
    //最后再进行格式化处理
    for(int i=0; i<n*n; ++i)
    {
        std::cout<<matrix[i];
​
        if((i+1)%n==0) std::cout<<std::endl;
    }
}

最后顺便说一嘴,这题其实也可以用字符串解决,不过思路都差不多(毕竟字符串某种程度上也算数组,只不过内置函数很方便)。

所以我们在解决问题时要充分利用现有的缓存工具,存储我们需要的数据来大大降低我们对过程思考的时间。不过这题还没有完全结束,下一个题就是这道题的逆转过程分析……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值