2017-09-08 16:00:21
原标题:20170830测试解题报告——OKVIRI
对于英文题啊,一直都是抱着敬仰大佬的心态去供着的。
然而今天发现,其实理解题意,和中文题都是一样的。
所以先来理解题意吧!
题上吧啦吧啦那么多,实际上很好理解,来一个形象的比喻:
你要定制一个手镯,基本底纹已经选定了,印花的时候呢你选了菱形的基本图案,还在中间加上了你的名字字母。
可是这样很丑啊,于是对菱形每三个改动一下,就满足你的需要了。
大意就是这样,现在可以分析啦!
输入:ABCD
输出:
..#...#...*...#..
.#.#.#.#.*.*.#.#.
#.A.#.B.*.C.*.D.#
.#.#.#.#.*.*.#.#.
..#...#...*...#..
其实题原来我没看懂‘*’要覆盖‘#’;但是样例真的很显眼啊。
所以现在就要讨论做法了
首先可以看到,这个是相对对称的,
所以说,其实第一行和第五行,第二行和第四行是可以一起写的。
首先我的思路是四个一段来看的,当然最开始也曾智障的看成五个。
其实是这样的
..#...#...*...#. .
.#.#.#.#.*.*.#.#.
#.A. #.B.*.C.*.D.#
.#.#.#.#.*.*.#.#.
..#...#...*...#..
(其实这个题的思路和一个小学题有点类似
摆正方形有没有!!!!)
那这就是这一段的代码了
这里“*4-3”其实是因为我后来做的加法运算,枚举开头;当然也可以改成“*4+1”,枚举结尾。加四是因为是分了四个一段,如果加一,将会很麻烦。
先来说一行和五行
..#. ..#. ..*. ..#. .
在第一段的时候,是k=1,a[k+2]= ‘#’
之后的都符合这个规律,所以很容易就推出来了。
开头是三的倍数是什么操作呢,是这样的:
K=9的时候,是第三个。21的时候是第六个
诸如此类。
然后是二行和四行
.#.# .#.# .*.* .#.# .
哇这行是真的很良心,k+1和k+3,原理基本相同
最后第三行,由于覆盖原因比较复杂
#.A. #.B. *.C *.D. #
首先k是菱形的符号,第k+2个就是字母喽。因为覆盖的原因,第三个和第四个都是“*”;
(k-4)%3==0意为上一个是三的倍数,也就是连续两个的情况。
k-4>0这个真的很要命,因为1-4=-3……
最后一行就是字母,之所以加三除以四是因为之前枚举开头,用的是除以四减三。
分析完了,上代码
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
char a[20];
char p[20][100];
int i=1;
int main()
{
freopen("OKVIRI.in","r",stdin);
freopen("OKVIRI.out","w",stdout);
int i=1;char ch;
while(scanf("%c",&ch))
{
if(ch=='n')break;
a[i++]=ch;
}
for(int j=1;j<=5;j++)
for(int k=1;k<=i*4+1;k++)
p[j][k]='.'; //最开始都赋成‘.’
for(int j=1;j<=5;j++)
{
for(int k=1;k<=i*4-3;k+=4)
{
if(j==1||j==5)
{
p[j][k+2]='#';
if(k%3==0)
p[j][k+2]='*';
}
if(j==2||j==4)
{
p[j][k+1]=p[j][k+3]='#';
if(k%3==0)
p[j][k+1]=p[j][k+3]='*';
}
if(j==3)
{
if(k%3==0||((k-4)%3==0)&&k-4>0)
{
p[j][k]='*';
}
else
p[j][k]='#';
p[j][k+2]=a[(k+3)/4];
}
}
}
for(int j=1;j<=5;j++){
for(int k=1;k<=i*4-3;k++)
printf("%c",p[j][k]);
printf("n");
}
}
最后提示一句,不要忘了文件操作。
作者: 凤台中学 陈诗思