码迷,mamicode.com
首页 > 其他好文 > 详细

外星人的房子(2015年4月第六届蓝桥杯)

时间:2015-04-12 13:21:27      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:

题目具体信息忘了,不过还能记得主要的信息,大致如下:

1.求外星人两个房子相距的最短距离

2..输入三个数wmn,分别表示列数、第一个房子、第二个房子

3.房子排列为从房号1开始,排满当前行后,从下一行的当前列开始,依次填充行中未填充的数字,房号依次递增,当输入w=-6m=8n=2时,显示图像部分如下:

 技术分享

图1

4.输出mn间的最短距离,样例输出为4.

题目分析:

(一)第一种思路

依次计算所有的数据,并填入二维数组,然后按行、列遍历之,求出mn的距离。

优点:不用寻找图形规律,可暴力破解。

缺点:花费的时间较多,当wmn较多时,无法AC

(二)第二种思路

通过图中显示数据,可以发现数据以为2倍的w为循环显示,那么就可以将数据按照两行划分,依次计算两行,接下来可能有人想到还是遍历数组,那就是又回到第一种思路了。接下来大家看看前两行的数据。

 技术分享

图2

在这里我们假设从左向右为正序,将正序定义为偶数行,逆序定义为奇数行,同时定义i表示当前行,那么在图2中对应的第一行就是第i = 0行,第二行就是第 i = 1行。

那么可以发现偶数行的数据evenData0 < (i * w) < evenData <= ((i + 1) * w),奇数行的数据oddData是 evenData < oddData <= (i + 1) * w。那么我们怎么把这两行数据表示出来呢?这就是第二种思路的关键了。

大家有没有发现,没两个房子间的距离,最短的走法只有两种,一种先行后列,一种先列后行。不论选取那种方式,都要求走到同行(列)后立即转向,否则就不是所求的最短路径。

解题关键来了,仔细观察图像后就会发现,两个房子间的最短距离是不是可以用行列下标进行运行得到?OK,正解。

那么问题是我们怎么将某个房子号转换为行列下标呢?这就要用到数据结构中的一维数组表示二维数组思想了。

既然我们将数据划分为两行每个模块,那么在进行转换时,就需要按照两行进行转换。

首先,转换行标。行标是最简单的直接除,可以得到式子①,其中的m表示房子序号:

row = m / w ;//

然后,转换列标。这个就有点技巧了,因为偶数行和奇数行的列标转换是不一样的,偶数行data2w取余之后,结果都是0<data<=w ,并且列序是正序,那么就可以表示为m % (2 * w) ,其中的;奇数行的data2w取余后,结果都是(w<data<=2w),这里就要注意列序的相减了,因为是逆序,每行有w个值,那么结果就是(w - m  %  w)。解决了?还没完呢,因为要知道m最小值为1,而我们要的下标是从0开始的,所以最后还要再减去一,整理之后就可以的出下面的式子②:

col = (m % (2 * w) > w ) ? (w - m  %  w) : m % (2 * w) - 1 ;//

最后,我们就要计算nm的距离了:

dec = abs(n_row - m_row) + abs(n_col - m_col);

其中的n_rowm_rown_colm_col可以套用公式①②求得。

到此,程序结束。

最后附上自己写的代码。

如果分析的有什么错误的地方希望各位看官指正,同时也希望有其他更好的解法:-D

 

技术分享
 1 #include <iostream>
 2 #include <iomanip>
 3 #include <math.h>
 4 using namespace std;
 5 
 6 int main(){
 7     int w , m , n ;
 8     cin >> w >> m >> n ;
 9     int m_i = m / w ;
10     int m_j = (m % (2 * w) > w ) ? (w - m % w) : m % (2 * w) ;
11     int n_i = n / w ;
12     int n_j = (n % (2 * w) > w ) ? (w - n % w ) : n % (2 * w)  ;
13     cout << m_i << "," << m_j << endl ;
14     cout << n_i << "," << n_j << endl ;
15     cout << abs(m_i - n_i) + abs(m_j - n_j) << endl ;
16     int ww = w * w ;
17     int sum = 0 ;
18     for(int i = 0 ; i < ww ; i += 2){
19         for(int j = 0 ; j < w ; j++){
20             cout << setw(5) << sum + j + 1 << " ";
21         }
22         cout << endl ;
23         sum += w ;
24         for(int j = w ; j > 0 ; j--){
25             cout << setw(5) << sum + j << " ";
26         }
27         sum += w ;
28         cout << endl ;
29     }
30     return 0;
31 }
View Code

 

外星人的房子(2015年4月第六届蓝桥杯)

标签:

原文地址:http://www.cnblogs.com/hugh-dark/p/4419331.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!