最近在 伟大的LG 的指导下开始玩了玩URAL的新手村,虽然说是非常简单的,但是还是遇到了一点小小的问题,卡住了进度。
在URAL的新手村里,竟然有一种题型出现了两次,那就是关于数组下标的计算,分别是URAL1319和1313。
先说说1313吧,这道题大概就是先输入一个数n,表示将有一个n*n的矩形,然后再给你这个矩形,让你按一种顺序输出。
这个顺序很好找,直接看样例就晓得了。
样例输入:
4
1 3 6 10
2 5 9 13
4 8 12 15
7 11 14 16
样例输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
很显然吧。
(要是觉得不显然,那就把你的脑袋逆时针旋转45°,然后你就发现了)
什么都不管,先输入了再说
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
cin>>a[i][j];
那么我们继续~
但是,看是很好看出来,但是怎么处理呢?
其实,就是一个简单的模拟过程而已。
把脑袋旋转之后,你会发现,前n行每行的数字个数和行数是一样的,那么,我们关于那半边的循环语句就已经很好写了(不要告诉我你不打算用循环写)
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cout<<a[A][B].........
这个很简单是吧?但是,我们怎么才能正确的输出呢?
准确的说,现在问题就转换成关于i和j的控制了。
可以发现,我们偏着脑袋看时,每一行的开始部分其实在我们正着脑袋看时,都相较于上一次往下走了一行,也就是说,我们的A和i是成正比的,但是,随着j的变化,我们的位置又是会一直往上走的,那么,这就是在告诉我们,A和j是成反比的。
所以,在A这个和式里,绝对有一个i-j
出现。
那么,A到底是什么呢?看看前后的边界条件,猜一猜就好了啦~(其实是可以找出来的,比如本人,当然也不是很复杂,并不是我体会的重点,就不再赘述了)。
其实A已经算的差不多了,只是在减的时候会减重一位,所以,我们最终的A是A=i-j+1
现在,我们来玩玩神奇的B这个和式吧~
神奇的发现,在偏着脑袋看时,每一行的开始位置在原来的矩形中都是第一列的!!也就是说,i的变化其实是和B无关的!
那么再继续考虑j,其实也不用考虑,你会神奇的发现当前位置的列数就是从第一列开始,然后到当前的第i列结束,所以,我们的B就很简单了:B=j
现在开始玩玩剩下的那一坨东西~一样的分析方法,还是继续旋转你的脑袋吧~当然,考虑到现在你看的前n行已经可以算出来了,所以自行用你的想象力去掉吧~
那么,剩下的那个东西其实比较有趣的(和一开始那个其实是比较相似的~)
嘿嘿嘿,具体发现的规律真的比较相似,那么,迭代i和j的循环语句直接摆上来就可以看懂了
for(i=n-1;i;i--)
for(j=1;j<=i;j++)
cout<<a[A][B]..............
很显然吧~
那么,我们再使用这种神奇的方法来计算啦~
在你脑袋逆时针旋转45°之后,会发现,每一行的开始位置在原来的那个矩形里面,都是从最后一行开始的!!!也就是说,A式里绝对有一个n出现,并且是没有i的!那么,我们再继续考虑j吧,在j增大的同时,当前的行是不断在上升的(也就是A的值在减小),所以说,A里绝对有一个-j的存在,然后,再考虑到相减会减重一个项,所以+1就好了呢~
所以,现在我们的A就计算出来了呢:A=n-j+1
很神奇吧~
再来B这个和式~还是通用的分析方法,在你斜着脑袋看时,每一个开始位置在原来矩形中的列数是随着i的减小而增大的,所以,B中一定有一个-i的存在。然后,i是从n-1开始的,所以B中还一定有一个n(想想为什么)!!!那么,随着j的增大,我们的列数也是在增大的,所以B中一定有一个j。
那么,B就如此愉快的算出来了~~B=n-i+j
。
好了,在把我完整的代码贴一遍吧~~
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
int a[110][110];
int main() {
int i,j,k,m,n;
cin>>n;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
cin>>a[i][j];
int cnt=0;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++){
cout<<a[i-j+1][j];
if(++cnt<n*n)cout<<" ";
}
for(i=n-1;i;i--)
for(j=1;j<=i;j++){
cout<<a[n-j+1][n-i+j];
if(++cnt<n*n)cout<<" ";
}
cout<<endl;
return 0;
}
神奇的是,在继续刷的时候我竟然还碰到了1319这么相似的题目,直接看样例,秒懂是在干什么:
样例输入:
3
样例输出:
4 2 1
7 5 3
9 8 6
懂了?(这次是把你的脑袋顺时针旋转45°)
相同的分析方法,就直接上代码了:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
int a[110][110];
int main() {
int i,j,k,m,n;
cin>>n;
int cnt=0;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
a[j][n-i+j]=++cnt;
for(i=n-1;i;i--)
for(j=1;j<=i;j++)
a[n-i+j][j]=++cnt;
for(i=1;i<=n;i++,cout<<endl){
for(j=1;j<n;j++,cout<<" ")
cout<<a[i][j];
cout<<a[i][n];
}
return 0;
}
就到这里鱼块的结束了,有没有对大家有一点帮助呢?麻烦大家点个赞吧~哈哈,谢谢大家。