C++面试题:循环数列问题

转载 2012年03月28日 23:08:05

21     22     23     24     25     …

20     7       8       9       10

19     6       1       2       11

18     5       4       3       12

17     16     15     14     13

看清以上数字排列的规律,设1点的坐标是(0, 0), x方向向右为正,y方向向下为正。例如,7的坐标为(-1, -1),2的坐标为(0, 1),3的坐标为(1, 1)。编程实现输入任意一点坐标(x, y), 输出所对应的数字。

 

先不妨在更大范围内考察各数字之间的关系:

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

210

157

158

159

160

161

162

163

164

165

166

167

168

169

170

227

209

156

111

112

113

114

115

116

117

118

119

120

121

122

171

228

208

155

110

73

74

75

76

77

78

79

80

81

82

123

172

229

207

154

109

72

43

44

45

46

47

48

49

50

83

124

173

230

206

153

108

71

42

21

22

23

24

25

26

51

84

125

174

231

205

152

107

70

41

20

7

 

8

9

10

27

52

85

126

175

232

204

151

106

69

40

19

6

1

2

11

28

53

86

127

176

233

203

150

105

68

39

18

5

4

3

12

29

54

87

128

177

234

202

149

104

67

38

17

16

15

14

13

30

55

88

129

178

235

201

148

103

66

37

36

35

34

33

32

31

56

89

130

179

236

200

147

102

65

64

63

62

61

60

59

58

57

90

131

180

237

199

146

101

100

99

98

97

96

95

94

93

92

91

132

181

238

198

145

144

143

142

141

140

139

138

137

136

135

134

133

182

239

197

196

195

194

193

192

191

190

189

188

187

186

185

184

183

240

 

当x > 0 时:

1,2,11,28,53,86, …                  (1)

他们之间的差分别是:

1,9,17,25,33…

这是一个公差为8的等差数列(arithmetic sequence),其第n项可以用a(n) = 1 + (n – 1) * 8表示,那么数列(1)的第n项可以表示如下:

x(n) = x(n – 1) + a(n) = x(n – 1) + 1 + (n – 1) * 8

由上面的公式,很容易想到需要用递归的方法来解决。由于要用到递归,因此x(n)的表达式中除x(n – 1)外,其他都必须展开。

 

同理,当x < 0时:

x(n) = x(n - 1) + 5 + (n - 1) * 8

上面的n是取了绝对值后的情况。

 

同理,当y > 0时:

y(n) = y(n – 1) + 3 + (n - 1) * 8

 

同理,当y < 0时:

y(n) = y(n – 1) + 7 + (n - 1) * 8

上面的n是取了绝对值后的情况。

 

解决上述问题的代码如下,应该有很大的改善空间。不过其优点就是不复杂,易懂。

// for x > 0

int calculateX(int n)

{

         if(n > 0)

         {

                   return calculateX(n - 1) + (1 + (n - 1) * 8) /*calculateIncrement(n - 1)*/;

         }

         else

         {

                   return 1;

         }

}

 

// for x < 0

int calculateMX(int n)

{

         if(n > 0)

         {

                   return calculateMX(n - 1) + (5 + (n - 1) * 8);

         }

         else

         {

                   return 1;

         }

}

 

// for y > 0

int calculateY(int n)

{

         if(n > 0)

         {

                   return calculateY(n - 1) + (3 + (n - 1) * 8);

         }

         else

         {

                   return 1;

         }

}

 

// for Y < 0

int calculateMY(int n)

{

         if(n > 0)

         {

                   return calculateMY(n - 1) + (7 + (n - 1) * 8);

         }

         else

         {

                   return 1;

         }

}

 

// calculate the value at specified coordinates

int calculate(int x, int y)

{

         int ret = 0;

         if ((x > 0) && (y > 0))

         {

                   if( x > y)

                   {

                            ret = calculateX(x) + y;

                   }

                   else

                   {

                            ret = calculateY(y) - x;

                   }

         }

 

         if ((x > 0) && (y < 0))

         {

                   if( x > abs(y))

                   {

                            ret = calculateX(x) + y;

                   }

                   else

                   {

                            ret = calculateMY(abs(y)) + x;

                   }

         }

 

         if ((x < 0) && (y < 0))

         {

                   if( abs(x) > abs(y))

                   {

                            ret = calculateMX(abs(x)) - y;

                   }

                   else

                   {

                            ret = calculateMY(abs(y)) + x;

                   }

         }

 

         if ((x < 0) && (y > 0))

         {

                   if( abs(x) > abs(y))

                   {

                            ret = calculateMX(abs(x)) - y;

                   }

                   else

                   {

                            ret = calculateY(y) - x;

                   }

         }

         return ret;

}

 

int main()

{

         int x = 0;

         int y = 0;

         cout << "Please enter coordinates. CTRL + Z to quit." << endl;

         while(cin >> x >> y)

         {

                   cout << "(" << x << ", " << y << ") = " << calculate(x, y) << endl;

         }

 

         return 0;

}


相关文章推荐

剑指offer面试题9 斐波那契数列及青蛙跳台阶问题

剑指offer面试题9 斐波那契数列 时间复杂度为N 青蛙跳台阶问题

【面试题】剑指offer09--菲波那切数列中的变态青蛙问题

【面试题】剑指offer09--菲波那切数列中的变态青蛙问题

基于Visual C++2013拆解世界五百强面试题--题14-循环删除

有一个数组a[1000]存放0-1000,要求每隔二个数删除一个数,到末尾时循环到开头继续进行,求最后一个被删掉数的原始下标。看到题目可以用循环链表保存这些数,然后循环删除,大大减少了一些复杂的边界判...

【百度面试题】循环有序数组的查找问题

问题: 有一个循环有序数组A,如{7,8,9,0,1,2,3,4,5,6},不知道其最小值的位置。 那么如何从这样的数组中寻找一个特定的元素呢? 解决: 当然,遍历总是一个办法。当然面试的时候...
  • uyehniy
  • uyehniy
  • 2012年04月12日 13:14
  • 188

剑指Offer面试题34题:丑数(Ugly Number)(while循环里面的三个小问题)

语言:C/C++语言 IDE:    Mac/Xcode  丑数:我们把只包含因子2、3、5的数称为丑数(Ugly Number),求按照从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不...

面试题12:打印1到最大的n位数-大数问题-递归实现多层循环

#include #include #include #include #include #include #include using namespace std; void p...

剑指offer算法题之循环链表--约瑟夫问题,面试题45:圆圈中最后剩下的数字(补充:define和typedef)

题目如下: 分析本题思路: 本题的原型就是约瑟夫环问题,有两种解决方法:第一种方法是用环形链表模拟圆圈的经典解法,第二种方法是分析每次被删除的数字的规律并直接计算出1圆圈中最后剩下的数字。本篇文章主...

循环数列问题(带数据)

  • 2013年03月31日 20:55
  • 10KB
  • 下载

面试题——C/C++经典问题,及面试笔试题

c语言中指针变量可以相加吗?其含义是什么? 指针变量是有加减运算的,但是要注意以下几点: 1.指针变量中存放的是地址值,也就是一个数字地址,例如某指针变量中的值是0x20000000,表示表示此指...

C/C++面试题--数组作为函数参数的几个问题

void fun(int array[10]) { int *p = &array[-1]; //p = &array[0] - 1; cout
  • jzp12
  • jzp12
  • 2012年06月22日 20:58
  • 762
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++面试题:循环数列问题
举报原因:
原因补充:

(最多只允许输入30个字)