我一直在想这个问题,我想不出用一种向外螺旋填充矩阵的方法,这样我就可以做到以下几点:
转过来: 1 2 3 4 5 ... n
要
21 22 23 24 25 26
20 07 08 09 10 27
19 06 01 02 11 28
18 05 04 03 12 29
17 16 15 14 13 30
...n
我的问题是算法本身,但是如果不是伪代码,你可以帮助使用C ++,那就更好了。
这是我写的一些代码来测试,但我真的不知道如何去做。
#include <stdio.h>
#include <string>
using namespace std;
int main() {
//int n = 5;
int spiral[5][6];
for (int i = 0; i < 5; i++)
for (int u = 0; u < 6; u++)
spiral[i][u] = 0;
spiral[2][2] = 1;
string direction = "right";
for (int i = 2; i < 5; i++) {
for (int u = 2; u < 6; u++) {
if (direction == "right") {
spiral[i][u + 1] = spiral[i][u] + 1;
direction = "down";
}
}
}
for (int i = 0; i < 5; i++) {
for (int u = 0; u < 6; u++) {
printf("%02d ", spiral[i][u]);
}
printf("\n");
}
return 0;
}
谢谢!
答案 0 :(得分:4)
您可以观察到左下角位置的相似方块具有最低值,然后向上,向右,向下和向左移动。
您可以使用它来创建这样的功能:
template <typename Array>
void spiral_square(Array& a, int x, int y, int side, int& value)
{
int mx = x+side-1, my=y+side-1;
for (int i = 1; i <= side-1; ++i) a[my-i][x] = value++;
for (int i = 1; i <= side-1; ++i) a[y][x+i] = value++;
for (int i = 1; i <= side-1; ++i) a[y+i][mx] = value++;
for (int i = 1; i <= side-1; ++i) a[my][mx-i] = value++;
}
查看实际操作:http://ideone.com/9iL1F
答案 1 :(得分:2)
从最后一个号码开始,从一个角落向内走。向一个方向移动,当你撞到墙壁时,向左转90度。
答案 2 :(得分:2)
我认为ipc的解决方案基于您总是希望填写整个矩阵的假设。如果你想做n = 28
(即有一些不完整的行或列)怎么办?
对于通用n
解决方案,我发现从起点开始最容易,并且知道旅行模式向外增量。请注意,你去了:
1对, 1下来, 2离开, 2起来, 3对, 3下来, 4离开, 4起来, 等
所以基本上这种模式是你向右,向下,向左,向上行进的步骤,每两个方向的变化都会增加。
不幸的是,我有一段时间没有用c ++编程,所以我用Ruby做过。
def output_spiral(n)
#For formatting, determine the length of the largest number
max_number_length = n.to_s.length
#Determine matrix size
max_x = Math.sqrt(n).floor
max_y = Math.sqrt(n).floor
if max_x * max_y < n
max_x += 1
if max_x * max_y < n
max_y += 1
end
end
#The a matrix of the required size.
#Note that for simplicity in printing spiral is an array of row arrays.
spiral = Array.new
row = Array.new(max_x){ |i| ' ' }
max_y.times{ spiral << row.clone }
#Determine the starting point index (ie where to insert 1)
x = ((max_x-1)/2).floor
y = ((max_y-1)/2).floor
#Input the start point value, formatted to the right size
spiral[y][x] = "%0#{max_number_length}d" % 1
#Setup counters required to iterate through the spiral
steps_in_direction = 1 #This defines how many steps to take in a direction
steps_count = 0 #This defines how many steps have been taken in the direction
direction = 'right' #This defines the direction currently travelling
steps_in_direction_count = 0 #This define how many times we have used the same steps_in_direction value
#Iterate through all the numbers up to n
2.upto(n) do |i|
#Change index based on the direction we are travelling
case direction
when 'right' then x += 1
when 'down' then y += 1
when 'left' then x -= 1
when 'up' then y -= 1
end
#Input the value, formatted to the right size
spiral[y][x] = "%0#{max_number_length}d" % i
#Increment counters
steps_count += 1
if steps_count == steps_in_direction
steps_count = 0
steps_in_direction_count += 1
if steps_in_direction_count == 2
steps_in_direction += 1
steps_in_direction_count = 0
end
case direction
when 'right' then direction = 'down'
when 'down' then direction = 'left'
when 'left' then direction = 'up'
when 'up' then direction = 'right'
end
end
end
#Output spiral
spiral.each do |x|
puts x.join(' ')
end
end
output_spiral(95)
参见http://ideone.com/d1N2c,其中n = 95的螺旋。
答案 3 :(得分:0)
我将假设这是针对项目euler#28(我前几天刚刚解决了这个问题)。秘诀不是创建矩阵,而是实现模式。实现模式,您可以在不创建矩阵的情况下计算出两个对角线。
1,3,5,7,9,13,17,21,25,...,n
跳过任何东西?
就重新创建螺旋矩阵而言,我认为最好的方法是在计算出模式后向后工作。从n开始,向下工作到1.在矩阵中放置'n'比1更容易。
编辑:
在确定对角线后创建矩阵并不太困难(问题28)。我将这些值放入矩阵中,然后根据我之前填充到矩阵中的主对角线值“遍历”填充所有其他值的矩阵。但是,我浪费了少量的时间来确定两个主要的对角线。我更喜欢IPC的解决方案。然而,正如另一种方法,这里是在之后计算矩阵的代码我确定了两个主要的对角线。设n指网格的大小,例如5。
int[,] t = new int[n, n];
int sizeOf = n - 1;
//Note that nums is the array of the two diagonals, which are already in sorted order based on my solution to problem 28.
//fill in diagonals
for (int diagNum = numsCount, i = sizeOf, j = 0; ; i--, j++)
{
if (diagNum < 3)
{
t[i, j] = 1;
break;
}
t[i, i] = nums[diagNum--];
t[i, j] = nums[diagNum--];
t[j, j] = nums[diagNum--];
t[j, i] = nums[diagNum--];
}
//finish filling in matrix
for (int i = sizeOf, c = 0; i > 1; i--, c++)
{
for (int j = i - 1; j > sizeOf - i; j--)
t[i, j] = t[i, i] - i + j;
for (int j = c + 1; j < sizeOf - c; j++)
t[c, j] = t[c, c] - j + c;
for (int j = c + 1; j < i; j++)
t[j, i] = t[c, i] - j + c;
for (int j = i - 1; j > c; j--)
t[j, c] = t[i, c] - i + j;
}
答案 4 :(得分:0)
#include<stdio.h>
main()
{
long int i,j,k,a,b,c,d,sum1=0,sum2=0,sum3=0,sum4=0;
for(i=1;i<=500;i++)
{
a=(2*i+1)*(2*i+1);
sum1=sum1+a;
b=a-2*i;
sum2=sum2+b;
c=b-2*i;
sum3=sum3+c;
d=c-2*i;
sum4=sum4+d;
}`
printf("%ld",sum1+sum2+sum3+sum4+1);``
}