UPC-分形图案

山再高,往上爬,总能登顶;
路再长,走下去,定能到达。

UPC-分形图案

题目描述

探险的过程是充满着艰辛和汗水的,为了调节自己的心情,我们的熊二经常会拿出他的漫画书来看,甚至他还梦想过以后要成为一个漫画家 
这一天,熊二被分形艺术吸引了,他研究了好久,决定以后把这些分形艺术的图案当作画布的主题。熊二拿出一张方格纸,
并开始制作他未来画布的模型。他把一个 n*n 的正方形中的若干个小格子涂成黑色(其余白色),然后他拿一张干净的方形纸片,
用下面的算法描绘分形: 
第 1 步:把纸分为 n*n 个相同的小方格,根据之前的模型将某些格子涂成黑色。 
步骤 2:把每个保持白色的小方格继续分成 n*n 个小方块,仍旧根据之前的模型涂色。 
接下来的每一步都重复第 2 步。如下图所示: 

在这里插入图片描述

随着图案越来越复杂,熊二表示自己已经蒙圈了。那么现在给你一个 n*n 的模型,请求出做 k 次重复的操作以后,最终的图像。 

输入

输入第一行是两个正整数n和k,n表示模型的长度,模型一定是一个正方形,k表示要重复操作的次数。
接下来n行,每行n个字符,’.’表示白色,’*’表示黑色

输出

输出有一个n^k*n^k的正方形矩阵,表示最终的图形,n^k表示n的k次方。

Sample Input

3 2
.*.
***
.*.

Sample Output

.*.***.*.
*********
.*.***.*.
*********
*********
*********
.*.***.*.
*********
.*.***.*.

Hint

共计有10个测试点。
对于70%的数据,保证n=2,k=2。
对于100%的数据,保证1<=n<=5,1<=k<=5。

思路解析
这道题的思路没啥知识点,硬说有的吧就是模拟了。
这题基本就是思路如下
1.确定位置
2.判断是否涂色
3涂色
复杂度不是很大,所以直接修改内容就可以。

题目大意
在这里插入图片描述
AC时间到
下面详细看代码中的注释,核心就是确定位置,判断是否涂色与否

#include<algorithm>
#include<iostream>
#include<string.h>
#include<utility>
#include<stdio.h>
#include<vector>
#include<string>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#pragma warning(disable:4244)
#define PI 3.1415926536
#pragma GCC optimize(2)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll ll_inf = 9223372036854775807;
const int int_inf = 2147483647;
const short short_inf = 32767;
const char char_inf = 127;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline ll read() {
	ll c = getchar(), Nig = 1, x = 0;
	while (!isdigit(c) && c != '-')c = getchar();
	if (c == '-')Nig = -1, c = getchar();
	while (isdigit(c))x = ((x << 1) + (x << 3)) + (c ^ '0'), c = getchar();
	return Nig * x;
}
inline void out(ll a)
{
	if (a < 0)putchar('-'), a = -a;
	if (a >= 10)out(a / 10);
	putchar(a % 10 + '0');
}
ll qpow(ll x, ll n, ll mod) {
	ll res = 1;
	while (n > 0) {
		if (n & 1)res = (res * x) % mod;
		x = (x * x) % mod; n >>= 1;
	}
	return res;
}
#define Floyd for(int k = 1; k <= n; k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)
#define read read()
char mark[200][200];
bool save[4000][4000];
void OUT(int lim)
{
	for (int i = 1; i <= lim; i++) {
		for (int j = 1; j <= lim; j++)
		{
			if (save[i][j])putchar('*');
			else putchar('.');
		}
		putchar('\n');
	}
}
void INPUT(int n)
{
	for (int i = 1; i <= n; i++)scanf("%s", mark[i] + 1);//确保第一个的位置是(1,1)
}
void color(int x, int y, int size)
{
	//这个x是根据上一步x+size(i-1)算出,y也同理。这样就可以求出来这个
	//需要改变颜色的坐标究竟在哪了
	int sx = x, sy = y, ex = x + size, ey = y + size;//STA(sx,sy),END(ex,ey)
	for (int i = sx; i < ex; i++)//末尾不可<=,最后一个不在当前区块内
		for (int j = sy; j < ey; j++)
			save[i][j] = 1;//改变bool值,输出时根据bool值输出即可
}
void change(int n, int x, int y, int size)
{
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)//判断该图像当前这块需不需要涂色
			if (mark[i][j] == '*')//如果需要
				color(x + size * (i - 1), y + size * (j - 1), size);//传入信息
}
int main()
{
	int n = read, k = read;//输入大小,输入次数
	INPUT(n);//输入
	int lim = qpow(n, k, 1e8);//来确定最终需要多少的空间来存这个数组,至少5^5=3125个
	for (int size = k; size >= 1; size--)
	{
		int x = qpow(n, size, 1e8);//判断当前所框定的操作区域
		for (int i = 1; i <= lim; i += x)//lim是边界
			for (int j = 1; j <= lim; j += x)//每次i,j都增加x
				if (!save[i][j])//该区域是白色区域,如果是白都是白,是黑都是黑
					change(n, i, j, x / n);//因为在框定区域操作的大小要小一级
	}
	OUT(lim);//输出
}

END

By-轮月

发布了39 篇原创文章 · 获赞 15 · 访问量 1835

猜你喜欢

转载自blog.csdn.net/qq_35339563/article/details/105428005
今日推荐