P1319 压缩技术
提交185.33k
通过79.94k
时间限制1.00s
内存限制125.00MB
提交答案加入题单
做题计划(首页)
个人题单
团队题单
保存
题目提供者yeszy
难度入门
历史分数0
标签
查看算法标签
相关讨论
查看讨论
推荐题目
查看推荐
洛谷推荐关闭
复制Markdown 展开
题目描述
设某汉字由 N×NN×N 的 00 和 11 的点阵图案组成。
我们依照以下规则生成压缩码。连续一组数值:从汉字点阵图案的第一行第一个符号开始计算,按书写顺序从左到右,由上至下。第一个数表示连续有几个 00,第二个数表示接下来连续有几个 11,第三个数再接下来连续有几个 00,第四个数接着连续几个 11,以此类推……
例如: 以下汉字点阵图案:
0001000
0001000
0001111
0001000
0001000
0001000
1111111
对应的压缩码是: 7 3 1 6 1 6 4 3 1 6 1 6 1 3 77 3 1 6 1 6 4 3 1 6 1 6 1 3 7 (第一个数是 NN ,其余各位表示交替表示0和1 的个数,压缩码保证 N×N=N×N= 交替的各位数之和)
输入格式
数据输入一行,由空格隔开的若干个整数,表示压缩码。
其中,压缩码的第一个数字就是 NN,表示这个点阵应当是 N×NN×N 的大小。
接下来的若干个数字,含义如题目描述所述。
输出格式
输出一个 N×NN×N 的 01 矩阵,表示最后的汉字点阵图(点阵符号之间不留空格)。
输入输出样例
输入 #1复制
7 3 1 6 1 6 4 3 1 6 1 6 1 3 7
输出 #1复制
0001000 0001000 0001111 0001000 0001000 0001000 1111111
说明/提示
样例解释
数据范围
数据保证,3≤N≤2003≤N≤200。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Practise_10._21_yasuojishu
{
internal class Program
{
static void Main(string[] args)
{
CompressionTechnology();
Console.ReadKey();
}
static void CompressionTechnology()
{
string input = Console.ReadLine();
string[] parts = input.Split(' ');
// 解析压缩码
int N = int.Parse(parts[0]);
List<int> counts = new List<int>();
for (int i = 1; i < parts.Length; i++)
{
counts.Add(int.Parse(parts[i]));
}
// 创建 N x N 矩阵
char[,] matrix = new char[N, N];
// 填充矩阵
int index = 0;
bool isZero = true; // 标记当前是填充0还是1
for (int i = 0; i < counts.Count; i++)
{
int count = counts[i];
for (int j = 0; j < count; j++)
{
if (index < N * N) // 确保不越界
{
matrix[index / N, index % N] = isZero ? '0' : '1';//确定输入数字位置
index++;
}
}
isZero = !isZero; // 切换填充的数字
}
// 输出矩阵
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
Console.Write(matrix[i, j]);
}
Console.WriteLine();
}
}
}
}
在代码理解中遇到的问题:
在这段代码中,matrix[index / N, index % N] = isZero ? '0' : '1';
这一行的目的是将字符 '0'
或 '1'
填充到一个二维数组 matrix
中。这里的 index
是一个一维的线性索引,用于确定在二维矩阵中的位置。
解释 index / N
和 index % N
-
index / N
:- 这个表达式计算出当前
index
所在的行号。因为矩阵是N x N
的,所以每一行有N
个元素。 - 例如,如果
index
是 5,且N
是 3,那么index / N
的结果是1
,表示第 2 行(行索引从 0 开始)。
- 这个表达式计算出当前
-
index % N
:- 这个表达式计算出当前
index
所在的列号。%
是取模运算符,它返回index
除以N
的余数。 - 例如,如果
index
是 5,且N
是 3,那么index % N
的结果是2
,表示第 3 列(列索引从 0 开始)。
- 这个表达式计算出当前
如何通过计算确定下一个数的位置
index
从 0 开始,随着每次填充矩阵的操作而递增。- 在每次填充时,
index
的值会增加,确保下一个填充的位置是下一个元素。 - 通过
index / N
和index % N
的组合,可以将一维索引index
转换为二维矩阵的行和列,从而在正确的位置填充'0'
或'1'
。
示例
假设 N = 3
,并且 counts
为 [2, 3, 1]
,则填充过程如下:
index = 0
: 填充matrix[0 / 3, 0 % 3]
→matrix[0, 0]
填充'0'
index = 1
: 填充matrix[1 / 3, 1 % 3]
→matrix[0, 1]
填充'0'
index = 2
: 填充matrix[2 / 3, 2 % 3]
→matrix[0, 2]
填充'1'
index = 3
: 填充matrix[3 / 3, 3 % 3]
→matrix[1, 0]
填充'1'
index = 4
: 填充matrix[4 / 3, 4 % 3]
→matrix[1, 1]
填充'1'
index = 5
: 填充matrix[5 / 3, 5 % 3]
→matrix[1, 2]
填充'0'
index = 6
: 填充matrix[6 / 3, 6 % 3]
→matrix[2, 0]
填充'0'
这样,程序就可以按照给定的压缩码正确地填充矩阵。
代码理解遇到的问题2
在这段代码中,List counts = new List();
这一行的作用是创建一个动态列表,用于存储从输入中解析出来的整数值(即压缩码中的计数)。具体来说,counts
列表将保存每个数字(0或1)的连续出现次数。
List<>
的作用
List<T>
是 C# 中的一个泛型集合类,提供了一个动态数组的实现。与数组不同,List
的大小是动态的,可以根据需要自动调整。以下是 List<T>
的一些主要特性和使用场景:
-
动态大小:
List
可以根据添加或删除元素的需要自动调整大小,而数组的大小在创建时是固定的。 -
类型安全:使用泛型时,
List<T>
可以确保列表中只包含特定类型的元素。例如,List<int>
只能存储整数。 -
丰富的方法:
List
提供了许多方便的方法,如Add()
,Remove()
,Contains()
,Sort()
,Clear()
等,使得对集合的操作更加简单和直观。
何时使用 List<>
- 当你需要一个可以动态调整大小的集合时。
- 当你不知道在编写代码时需要存储多少个元素。
- 当你需要频繁地添加或删除元素。
- 当你希望利用
List
提供的丰富方法来处理集合。
在这段代码中,List<int>
被用来存储从输入中解析出的计数值,以便后续填充矩阵。由于输入的计数值的数量是动态的,使用 List<int>
是一个合适的选择。
代码整体理解分析:
using System;
using System.Collections.Generic;
- 引入
System
命名空间,提供基本功能(如输入输出)。 - 引入
System.Collections.Generic
命名空间,允许使用泛型集合(如List<T>
)。
csharp复制代码
class Program { static void Main()
- 定义一个名为
Program
的类。 - 定义
Main
方法,这是程序的入口点。
csharp复制代码
// 读取输入 string input = Console.ReadLine();
- 从控制台读取一行输入,并将其存储在
input
字符串中。
csharp复制代码
string[] parts = input.Split(' ');
- 将输入字符串按空格分割成多个部分,存储在字符串数组
parts
中。
csharp复制代码
// 解析压缩码 int N = int.Parse(parts[0]);
- 将
parts
数组的第一个元素(表示矩阵的大小 N)转换为整数,并存储在变量N
中。
csharp复制代码
List<int> counts = new List<int>();
- 创建一个整数列表
counts
,用于存储后续的压缩码。
csharp复制代码
for (int i = 1; i < parts.Length; i++) { counts.Add(int.Parse(parts[i])); }
- 从
parts
数组的第二个元素开始,遍历所有元素,将它们转换为整数并添加到counts
列表中。
csharp复制代码
// 创建 N x N 矩阵 char[,] matrix = new char[N, N];
- 创建一个 N x N 的字符矩阵
matrix
,用于存储最终的输出。
csharp复制代码
// 填充矩阵 int index = 0; bool isZero = true; // 标记当前是填充0还是1
- 初始化
index
为 0,用于跟踪当前填充矩阵的位置。 isZero
布尔变量用于标记当前填充的是 ‘0’ 还是 ‘1’。
csharp复制代码
for (int i = 0; i < counts.Count; i++) { int count = counts[i];
- 遍历
counts
列表中的每个元素,count
表示当前要填充的数量。
csharp复制代码
for (int j = 0; j < count; j++) { if (index < N * N) // 确保不越界 { matrix[index / N, index % N] = isZero ? '0' : '1'; index++; } }
- 对于每个
count
,执行一个内部循环,填充矩阵。 - 检查
index
是否小于N * N
,以确保不越界。 - 使用
index / N
和index % N
计算当前填充的位置,并根据isZero
的值填充 ‘0’ 或 ‘1’。 - 增加
index
以移动到下一个位置。
csharp复制代码
isZero = !isZero; // 切换填充的数字 }
- 切换
isZero
的值,以便在下一个循环中填充相反的数字。
csharp复制代码
// 输出矩阵 for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { Console.Write(matrix[i, j]); } Console.WriteLine(); } }
- 外层循环遍历矩阵的每一行,内层循环遍历每一列,输出矩阵的内容。
- 每输出完一行后,调用
Console.WriteLine()
输出换行符,以便格式化输出。