P1320 压缩技术(续集版)

题目描述

设某汉字由 N×NN \times NN×N0\texttt 001\texttt 11 的点阵图案组成。

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

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

0001000
0001000
0001111
0001000
0001000
0001000
1111111

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

输入格式

汉字点阵图(点阵符号之间不留空格)。

输出格式

输出一行,压缩码。

说明/提示

数据保证,3≤N≤2003\leq N\leq 2003N200


问题分析

还记得上一题P1320 压缩技术的过程吗?这一题就是反过来的步骤,这一次是先给点阵后输出压缩码。

按道理来说思路很简单,数清楚每一串0和1的个数就行了,不过在实际编写代码上,肯定会被两个与思路无关却十分关键的问题卡住:输入怎么操作? 输出怎么操作?

可以看到,这里的输入格式是直接来的字符串,换句话说,每一行中的数字是没有分割的,输入缓冲区会一股脑把一行的数据都算进来。如果你设置的变量类型是int或者bool,那可能储存的就和你预想的数据不一样了。因此,我们先使用字符串存储每一行,再进行遍历获取一行内的每个元素。每执行一次这个过程便需要用到一次for循环。

但是还有一个问题,这题虽然是一个 N×NN \times NN×N 的输入, NNN 是多少呢?输入时并没有显性地提供。这里我们需要先读取一行的数据,搞清楚 NNN 为何物之后,才能进行更后续的处理。因此,第一行需要单独拎出来处理。

std::cin>>str;

sum=str.size();//获取N

for(int i=0; i<sum; ++i)
{
    matrix[i]=bool(str[i]-'0');
}
//第一行重新整理

这里的重新处理就是提取一行内的元素到数组里。

接着就好办了,对剩余的每一行进行处理。

for(int i=1; i<=sum-1; ++i)
{
    std::cin>>str;
    for(int j=0; j<sum; ++j)
    {
        matrix[i*sum+j]=bool(str[j]-'0');
    }
}
//输入后几行

接着是输出。其实输出有两种思路完成。一种是保存数据再输出,另一种是直接输出保存数据就是统计每处0或1的总数,将其存储至一个容器里(数组或者向量),这是我一开始的思路;直接输出就是每统计完一次数据就直接进行输出,这是我为了缩短代码长度想到的思路。这里我写下的是直接输出,更加简便一些。

统计数据时的切换条件无非就是判断下一个元素是否与当前元素一致,如果不一致,保存或输出当前统计值,然后初始化为1,再统计下一数据。

for(int i=0; i<sum*sum; ++i)
{
    if(i==sum*sum-1)
    {
        currsum++;
        std::cout<<currsum;
        break;
    }//这是处理统计至末尾元素时的跳出判断
    
    if(matrix[i]!=flag)
    {
        flag=matrix[i];
        std::cout<<currsum<<" ";
        currsum=1;
    }//下一元素不同于当前元素时(统计完当前元素)跳出条件
    else currsum++;
    //相同则继续统计
}

这一题的变量初始化和上一题压缩技术基本一致,这里不做赘述。


代码

#include<iostream>
#include<string>

//P1320 压缩技术(续集版)
int main(){
    bool num;
    bool flag=0;	//判断元素变化的基准变量
    bool matrix[114514];
    int sum=0, currsum=0;	//统计一行元素个数和0或1个数
    std::string str;
    
    std::cin>>str;	//输入第一行

    sum=str.size();

    for(int i=0; i<sum; ++i)
    {
        matrix[i]=bool(str[i]-'0');
    }
    //第一行重新整理

    for(int i=1; i<=sum-1; ++i)
    {
        std::cin>>str;
        for(int j=0; j<sum; ++j)
        {
            matrix[i*sum+j]=bool(str[j]-'0');
        }
    }
    //输入后几行

    std::cout<<sum<<" ";

    for(int i=0; i<sum*sum; ++i)
    {
        if(i==sum*sum-1)
        {
            currsum++;
            std::cout<<currsum;
            break;
        }

        if(matrix[i]!=flag)
        {
            flag=matrix[i];
            std::cout<<currsum<<" ";
            currsum=1;
        }
        else currsum++;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值