十字架(百度2017秋招真题)深入解析
程序员文章站
2022-05-12 22:36:36
...
题目链接
首先这个题目必定是递归思想,因为大的图形当中又会套上小的图形
其次必须先确定图形的中点,因为由图形的中点可以确定下来图形的位置,从中间向周围加上中间五个方向分布进行递归图形,这里我通过递归一个图形的四个边界进行中点位置的递归
这里关键是求出data1与data2的长度,从而能够继续进行递归
data1可以看成是3的0次方加3的1次方一直加到3的n-3次方的和
使用次方叠加公式可得相应的结果
data2为3的n-2次方
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define N 1000
char s[N][N];
void prints(int n,int rowstart,int rowend,
int columnstart,int columnend)
{
if(n == 1&&rowstart == rowend&&columnstart == columnend)
{
s[rowstart][columnstart] = 'o';
}
else
{
int data1 = (int)(pow(3.0,n-2)+0.5)-1;
data1 = data1/2;
//data1利用次方的求和公式求出,+0.5是为了避免pow函数所带来的误差
int data2 = (int)(pow(3.0,n-2)+0.5);
//data2通过n-2次方求出结果
int rowmiddle = (rowstart+rowend)/2;
int columnmiddle = (columnstart+columnend)/2;
prints(n-1,rowmiddle-data1-data2,rowmiddle-data1-1,
columnmiddle-data1,columnmiddle+data1);
//递归出左边图形的起始坐标,终止坐标
prints(n-1,rowmiddle+data1+1,rowmiddle+data1+data2,
columnmiddle-data1,columnmiddle+data1);
//递归出右边图形的起始坐标,终止坐标
prints(n-1,rowmiddle-data1,rowmiddle+data1,
columnmiddle-data1-1,columnmiddle-data1-data2);
//递归出上面图形的起始坐标,终止坐标
prints(n-1,rowmiddle-data1,rowmiddle+data1,
columnmiddle+data1+1,columnmiddle+data1+data2);
//递归出下面图形的起始坐标,终止坐标
prints(n-1,rowmiddle-data1,rowmiddle+data1,
columnmiddle-data1,columnmiddle+data1);
//递归出中间图形的起始坐标,终止坐标
}
}
int main(){
int n1;
scanf("%d",&n1);
for(int u=1;u<=n1;u++)
{
fill(s[0],s[0]+N*N,' ');
int n;
scanf("%d",&n);
int data = (int)(pow(3.0,n-1)+0.5);
int total = (int)(pow(3.0,n-1)+0.5);
int middle = (1+data)/2;
prints(n,1,data,1,data);
printf("Case #%d:\n",n1);
for(int i=1;i<=total;i++)
{
for(int j=1;j<=total;j++)
{
printf("%c",s[i][j]);
if(j == total)
{
printf("\n");
}
}
}
}
return 0;
}
上一篇: 怎么向零基础的同学讲解栈?