我正在为this problem实现一个解决方案,以便对这种语言有所了解。我的推理如下:
请注意,对角线上的图案为2*n+1
。
左侧和上方的元素是对角线到边界的交替算术级数或元素的加法/减法。
创建2D向量并实例化所有对角线元素。然后创建一个虚拟变量,以通过添加/减去对角线元素来填充其余部分。
我的代码如下:
#include <vector>
using namespace std;
const long value = 1e9;
vector<vector<long>> spiral(value, vector<long> (value));
long temp;
void build(){
spiral[0][0] = 1;
for(int i = 1; i < 5e8; i++){
spiral[i][i]= 2*i+1;
temp = i;
long counter = temp;
while(counter){
if(temp % 2 ==0){
spiral[i][counter]++;
spiral[counter][i]--;
counter--;
temp--;
}else{
spiral[i][counter]--;
spiral[counter][i]++;
counter--;
temp--;
}
}
}
}
int main(){
spiral[0][0] = 1;
build();
int y, x;
cin >> y >> x;
cout << spiral[y][x] << endl;
}
问题是程序没有输出任何东西。我不知道为什么我的向量不会打印任何元素。我已经用spiral[1][1]
进行了测试,等待5或10分钟后,我得到的只是一些晦涩的汇编程序消息。我的推理怎么了?
编辑:完整输出为:
和
答案 0 :(得分:0)
long
对您来说可能是4或8字节(例如,在Windows上通常为4字节,在x86 Linux上通常为4字节,在x64 Linux上通常为8字节),因此假设4。1e9 * 4
为每个vector<long> (value)
都有4 GB的连续内存。
然后,外部向量将创建另一个1e9
副本,即4艾字节(或400万兆字节),给定32位长或64位加倍,并忽略每个std::vector
的开销大小。您不太可能拥有那么多的内存和交换文件,并且要成为全局变量,请在调用main()之前尝试 。
因此,您将无法直接存储所有这些数据,您将需要考虑实际需要存储哪些数据才能获得所需的结果。
如果您在设置为在异常情况下停止运行的调试器下运行,则可能会抛出std::bad_alloc
,并在调用堆栈中指明原因(例如,Visual Studio将显示类似“动态初始值设定项(在调用堆栈中为“螺旋”)),但在Linux上,操作系统可能会先杀死它,因为Linux会过量使用内存(因此new
等成功),然后在某些程序会使用内存(实际的读取或写入)而失败(超额提交,没有任何空闲空间),并且SIGKILL可以释放内存(这似乎并非完全可预见,我将代码复制粘贴到Ubuntu 18上并在命令行上得到了““在抛出'std :: bad_alloc'实例后调用终止”)。
答案 1 :(得分:0)
数学是您的朋友,不是std::vector
。这个难题的限制因素之一是512 MB的内存限制,但是一个足以进行所有测试的向量将需要数GB的内存。
考虑正方形的填充方式。如果您在给定的x
和y
之间选择 maximum (称其为w
),则“定界”一个大小为w 2的正方形。现在,您必须考虑该正方形的外边缘以找到实际的索引。
例如取x = 6且y =3。最大值为6(即使还记得锯齿形图案),所以数字为(6-1-) 2 + 3 = 28
* * * * * 26 * * * * * 27 * * * * * [28] * * * * * 29 * * * * * 30 36 35 34 33 32 31
Here,这是概念证明。
答案 2 :(得分:0)
问题实际上是要求您找到解决方案的解析公式,而不是模拟模式。您需要做的就是仔细分析模式:
unsigned int get_n(unsigned int row, unsigned int col) {
assert(row >= 1 && col >= 1);
const auto n = std::max(row, col);
if (n % 2 == 0)
std::swap(row, col);
if (col == n)
return n * n + 1 - row;
else
return (n - 1) * (n - 1) + col;
}