1021.从前有座山

Description

从前有座山,山的俯视图是一个n×n的矩形,(1,1)位置海拔最低为1,然后海拔沿环形依次升高。

给定n的值,输出这座山的海拔高度图。

Input Format

输入仅有一行,为一个正整数n。

Output Format

输出为这座山的海拔高度图。

Sample Input

4

Sample Output

     1     2     3     4
    12    13    14     5
    11    16    15     6
    10     9     8     7

题目来源是上海交大acm题库,地址http://acm.sjtu.edu.cn/OnlineJudge/problem/1021

google了一下,网上现有的做法似乎都没有我的好,所以把我的做法贴出来^_^。

基本的思路是开辟一个n * n的矩阵,填上表示高度的数字,再输出这个矩阵。

问题在于如何填上正确的数字。

以 n = 5 为例子,观察最外圈的数字,将其分为4个部分,如图

显然,每个部分都可以用一个循环来填充数字。不失一般的,填充一整圈的伪代码为:

for i = 1..N

map[1][i] = i

map[i][N] = N - 1 + i

map[N][N - i] = 2 * (N - 1) + i

map[N - i][1]= 3 * (N - 1) + i

对于非最外圈而言,记录下起始填充位置的偏移量(包括x轴偏移,y轴偏移,填充数字偏移)即可。

最后,对于奇数边长矩阵,需要在矩阵的中心点填上高度的最大值,也就是边长的平方。


#include <iostream>
#include <iomanip>
#include <string.h>

using namespace std;

int main(){

	int i, j;
	int n;
	int *map;

	cin >> n;
	map = new int[n * n];
	memset(map, 0, sizeof(map));

	int h_offset = 1;
	int x_offset = 0;
	int y_offset = 0;

	for (int len = n - 1; len > 0; len-= 2){	//a loop fills a circle, from outer to inner

		for (i = 0; i < len; ++i){

			map[x_offset * n + (y_offset + i)] = h_offset + i;
			map[(x_offset + i) * n +  (n - 1 - y_offset)] = h_offset + len + i;
			map[(n - 1 - x_offset) * n + (n - 1 - y_offset - i)] = h_offset + 2 * len + i;
			map[(n - 1 - x_offset - i) * n + (y_offset)] = h_offset + 3 * len + i;

		}

		h_offset += 4 * len;
		x_offset ++;
		y_offset ++;

	}

	if(n % 2 == 1)
		map[n * n / 2] = n * n;

	for (i = 0; i < n; ++i){
		for (j = 0; j < n; ++j){
			cout << setw(6) << map[i * n + j];
		}
		cout << endl;
	}

	delete []map;
	return 0;
}
时间: 2024-11-09 04:58:32

1021.从前有座山的相关文章

1021. 从前有座山——java

1021. 从前有座山 Description 从前有座山,山的俯视图是一个n×n的矩形,(1,1)位置海拔最低为1,然后海拔沿环形依次升高. 给定n的值,输出这座山的海拔高度图. Input Format 输入仅有一行,为一个正整数n. Output Format 输出为这座山的海拔高度图. Sample Input 4 Sample Output 1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 7 Hint 首先程序#include <iomanip> 假设要输出

ACM 1021. 从前有座山(用机器判断,代替公式计算)

1021. Deepest Root (25) 并查集&amp;&amp;DFS

1021. Deepest Root (25) 时间限制 1500 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root t

HDU 1021[Fibonacci Again]规律

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1021 题目大意:首两项为7,11的斐波那契数列.若第n项能被3整除,输出yes,否则输出no 关键思想:模三加法情况有限,找规律. 代码如下: #include <iostream> using namespace std; int main(){ int n; while(cin>>n) if(n%8==2||n%8==6)cout<<"yes"<

BZOJ 1021: [SHOI2008]Debt 循环的债务( dp )

dp(i, j, k)表示考虑了前i种钱币(从小到大), Alice的钱数为j, Bob的钱数为k, 最小次数. 脑补一下可以发现, 只有A->B.C, B->A.C, C->A.B, A.B->C, A.C->B, B.C->A 6情况, 枚举然后dp一下就OK了. dp用刷表的话,有个强有力的剪枝是之后的硬币无论如何组合都无法满足时不去更新. --------------------------------------------------------------

【BZOJ】【1021】【SHOI2008】Dept循环的债务

DP 去膜拜题解了>_>玛雅原来是动规…… 让我先理解一下为什么要用动规:这个题根据钱数推方案其实是无从下手的……(线性规划?……事实证明我想多了) 啦-我们先来看个超级简化版的问题:怎么判无法还清?正着判很麻烦对不对= =(其实是我没想……) 那么我们倒着来考虑:有哪些状态是我们通过交换钱币能够到达的,这个可以递推对不>_> 现在我们就知道哪些状态我们是可以到达的了……再多想一下……递推……如果我们依次考虑每种面额的交换策略,顺便也就知道了我们到达这个状态的最小交换次数对吧? 原

1021. 个位数统计

1 /* 2 * Main.c 3 * 1021. 个位数统计 4 * Created on: 2014年8月30日 5 * Author: Boomkeeper 6 ********测试通过****** 7 */ 8 9 #include <stdio.h> 10 #include <string.h> 11 12 int main(void){ 13 14 char str[1001]; 15 int num[10]={-1}; 16 int len; 17 int i; 18

PAT 1021. Deepest Root (25)

1021. Deepest Root (25) A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root that results in a highest tree. Such a root is called the deepest root

杭电 1021 Fibonacci Again

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1021 解题思路:根据之前发现斐波那契数列的规律,即为f(n)能被3整除当且仅当n能被4整除. 于是联想到这道题目,它只是改变了f(0)和f(1)的值,肯定也一样有规律可以寻找 f(0)=7; f(1)=11; f(2)=18;能整除3 f(3)=29; f(4)=47; f(5)=76; f(6)=123;能整除3 f(7)=200; f(8)=323; f(9)=523; f(10)=846;能整