题解 第二章暴力求解| #Repeater#
Repeater
http://www.nowcoder.com/practice/97fd3a67eff4455ea3f4d179d6467de9
法1:
我的思路及其简单
实现及其复杂
运行有5ms
主要思路是首先将模板矩阵,读入一个5*5的Temp矩阵中
计算出将要打印内容的矩阵大小
随后在足够大的ForPrint矩阵中,逐个位置遍历,确定其符号
是空格还是其他
确定符号的方法是:
考虑最外层,可以看做是次外层,按照原来模板的状态逐个对应的
凡是原来模板有空格的,当前次外层模块全部为空格
对每个点都遍历所有层次,一旦发现位于某一层的空格次外层模块时
则设置空格标记,并跳出层次遍历的循环
只有当所有层都不是空格时,才按照原给定模板对其赋值
//通过公式计算,得到新的矩阵
#include <stdio.h>
#include <math.h>
#define MAXSIZE 150
//将给定模板复制
void Repeat(char (*Temp)[5], int Size,
char (*ForPrint)[MAXSIZE],
int RepeatTime)
{
int PrintSize = pow(Size, RepeatTime);
int SpaceFlag = 0; //用于标记是否在复制过程中有一次是空格
//遍历ForPrint数组,写入对应值
for (int i = 0; i < PrintSize; i++)
for (int j = 0; j < PrintSize; j++)
{
SpaceFlag = 0;
for (int k = 1; k <= RepeatTime; k++)
{
int useful = pow(Size, k);
int temp_i = floor(((i % useful)) / (pow(Size, k - 1)));
int temp_j = floor((j % useful) / (pow(Size, k - 1)));
if (Temp[temp_i][temp_j] == ' ')
{
SpaceFlag = 1;
break;
}
}
if (SpaceFlag)
ForPrint[i][j] = ' ';
else
ForPrint[i][j] = Temp[i % Size][j % Size];
}
}
//具体打印出已经保存好的值
void PrintForPrint(char (*ForPrint)[MAXSIZE], int Size, int RepeatTime)
{
int PrintSize = pow(Size, RepeatTime);
//将各行各列打印出来
for (int i = 0; i < PrintSize; i++)
{
for (int j = 0; j < PrintSize; j++)
printf("%c", ForPrint[i][j]);
printf("\n");
}
}
int main()
{
int Size = 0;
int RepeatTime = 0;
char Temp[5][5] = {0};
char ForPrint[MAXSIZE][MAXSIZE] = {0};
char c;
int flagN = 0; //用于保存第几个数字
int flagL = 0; //用于保存已经存入了多少行
int flagFirstLine = 0; //用于剔除第一个行号
int flagLastLine = 0; //用于剔除最后一个行号
int LineNum = 0;
while (scanf("%c", &c) != EOF)
{
if (flagN == 1 && flagL != Size)
{
if (c == '\n')
{
if (flagLastLine == 1)
{
flagLastLine = 0;
flagN = 0;
continue;
}
else if (flagFirstLine == 1)
{
flagFirstLine = 0;
LineNum = 0;
continue;
}
else
{
flagL++, LineNum = 0;
continue;
}
}
Temp[flagL][LineNum++] = c;
}
if (flagLastLine == 0 && flagN == 0 && flagFirstLine == 0)
{
if (c == '0')
break;
flagN++;
flagFirstLine = 1;
Size = c - '0';
}
if (flagL == Size)
{
flagL = 0;
flagLastLine = 1;
RepeatTime = c - '0';
Repeat(Temp, Size, ForPrint,
RepeatTime);
PrintForPrint(ForPrint, Size, RepeatTime);
}
}
}
法2:
借鉴别人的做法
他用的方法与我不同
使用了递归的方法
递归一层的参数分别是q,x,y
其中q是递归层级
x,y分别是起始点的坐标
首先,初始模板存入t矩阵中
p矩阵为待画矩阵
两者均为全局变量
递归出口为层数为1时,即将从对应的x,y位开始的模块填充进去
在一般情况下,则遍历当前层次的次层次模块
若该次层次模块不为空格时,则递归遍历该次层次模块
#include <stdio.h>
#include <math.h>
int N, Q;
char t[6][6];
char p[3000][3001];
void draw(int q, int x, int y)
{
int eSize = (int)pow(N, q - 1);
int i, j;
if (q == 1)
{
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
p[x + i][y + j] = t[i][j];
}
}
}
else
{
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
if (t[i][j] != ' ')
{
draw(q - 1, x + eSize * i, y + eSize * j);
}
}
}
}
}
int main()
{
while (scanf("%d", &N) != EOF)
{
if (N == 0 || N > 5)
{
break;
}
//去掉多余的换行符
getchar();
//输入模板
int i, j;
for (i = 0; i < N; i++)
{
gets(t[i]);
}
scanf("%d", &Q);
int size = (int)pow(N, Q);
//格式化图画
for (i = 0; i < size; i++)
{
for (j = 0; j < size; j++)
{
p[i][j] = ' ';
}
p[i][size] = '\0';
}
draw(Q, 0, 0);
for (i = 0; i < size; i++)
{
puts(p[i]);
}
}
return 0;
}
接下来学习他的字符串操作
使用c=getchar();可以一次读取一个字符,多余的键盘上的字符全部存入键盘buff中
使用gets(char*);可以读入一行数据,遇到换行符则退出;但是容易被蠕虫攻击,故不能用gets().
法3:
//每次将不为空格的字符替换为模板即可
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void duplicate(vector<string> &s, vector<string> &temp)
{
string SpaceString(s.size() * temp.size(), ' ');
vector<string> res(s.size() * temp.size(), SpaceString);
//新的res是用来保存下一层待打印数据的
// s中是已有层待打印数据
for (int i = 0; i < s.size(); i++)
{
for (int j = 0; j < s[i].size(); j++)
{ //这两个for循环用于遍历之前的s[]数组
if (s[i][j] != ' ') //若不是空格,才将输入模板,复制到下一层待打印数据res中去
{
for (int k = 0; k < temp.size(); k++)
{ //这个循环用于将每一行的模板数字,复制到res中
//当前行在res中定位在i*temp.size()+k这一行
res[i * temp.size() + k].replace(
res[i * temp.size() + k].begin() + j * temp.size(),
res[i * temp.size() + k].begin() + j * temp.size() + temp.size(),
temp[k]);
} // begin()返回容器指针
// replace(*type,int count,*templ)或者replace(*begin,*end,*templ)
//此for循环结束后,原模板的逐行拷贝即完成
}
}
}
s = res;
}
int main()
{
int N, Q;
while (cin >> N)
{
if (N == 0)
return 0;
vector<string> temp(N);
getline(cin, temp[0]); //用于取出第一行数字之后的'\n',并在后面进行覆盖
//取到\n时,getline自动结束本行,其中不存入\n
//故此时temp[0]中什么也没有
cout << temp[0];
for (int i = 0; i < N; getline(cin, temp[i++]))
;
vector<string> res(temp); //直接复制过来了temp动态数组
//此处是第一层
cin >> Q;
for (int i = 1; i < Q; i++)
{
duplicate(res, temp);
} //根据层数逐级增大即可
for (int i = 0; i < res.size(); i++)
{
cout << res[i] << endl;
}
}
}
王道机试指南刷题 文章被收录于专栏
计划刷完这本书