Files
dl/build/backup/Demo1.cpp
T
2026-09-16 14:07:40 +08:00

227 lines
4.1 KiB
C++
Vendored

// Demo1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <unordered_set>
#include <unordered_map>
#include <string>
#include <variant>
#include <cstdint>
#include <stacktrace>
#include <windows.h>
void print(int x, int y, std::string str) {
COORD p = { x, y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), p);
std::cout << str;
}
// 2D环形遍历
// 中心点是数学坐标(0, 0), 每环从右下(N, -N)开始逆时针遍历
void RingSearch_Next(int& nX, int& nY)
{
// 开始
if (nX == 0 && nY == 0)
{
nX = 1;
nY = -1;
return;
}
// 下1环(右下)
if (nY<0 && nX+nY== -1)
{
++nX; // 到右下
// 下1环
++nX;
--nY;
return;
}
// 右边线(向上)
if (nY+nX>=0 && nY-nX<0)
{
++nY;
return;
}
// 上边线(向左)
if (nY - nX >= 0 && nY + nX > 0)
{
--nX;
return;
}
// 左边线(向下)
if (nY + nX <= 0 && nY - nX > 0)
{
--nY;
return;
}
// 下边线(向右)
if (nY-nX<=0 && nY+nX<0)
{
++nX;
return;
}
// 无法到这里
int x = 0;
x++;
}
// 2D环形遍历
// 中心点是数学坐标(0, 0), 每环从右下(N, -N)开始逆时针遍历
// 根据序号直接计算点坐标
void RingSearch_Index(int nIndex, int& nX, int& nY)
{
// (0, 0) 做为第0环, 且 nIndex=0
if (nIndex <= 0)
{
nX = 0;
nY = 0;
return;
}
// 次外层第K环, 共有 (2K+1)*(2K+1)个点
// 最外层
int k = (sqrt(nIndex) + 1) / 2;
// 第k环点的序号
int nIdx = nIndex - (2*k-1)*(2*k-1);
// 第k环每条边的点数
int nL = 2 * k; // 只能包含一个端点
// 第几条边的第几个点
int nD = nIdx / nL;
int nIdx2 = nIdx % nL;
// (下面边的序号对应的边可以随意修改: 代表了不同的遍历方法)
switch (nD)
{
case 0:
// 第一条边(右)
nX = k;
nY = -k;
nY += nIdx2;
break;
case 1:
// 第二条边(上)
nX = k;
nY = k;
nX -= nIdx2;
break;
case 2:
// 第三条边(左)
nX = -k;
nY = k;
nY -= nIdx2;
break;
case 3:
// 第四条边(下)
nX = -k;
nY = -k;
nX += nIdx2;
break;
default:
// 出错
break;
}
}
// 2D环形遍历
// 中心点是数学坐标(0, 0), 每环从右下(N, -N)开始逆时针遍历
// 根据点坐标计算序号(从0开始)
int GetRingIndex(int nX, int nY)
{
if (nX == 0 && nY == 0)
{
return 0;
}
int k = max(abs(nX), abs(nY));
// 环内的数量
int nN = (2 * k - 1) * (2 * k - 1);
// 边长
int nL = 2 * k;
if (nX == k && nY != k)
{
// 第一边(右)
nN += (k + nY);
}
else if (nY == k && nX != -k)
{
// 第二边(上)
nN += 2*k;
nN += (k - nX);
}
else if (nX == -k && nY != -k)
{
// 第三边(左)
nN += 4 * k;
nN += (k-nY);
}
else if(nY == -k && nX != k)
{
// 第四边(下)
nN += 6 * k;
nN += (k + nX);
}
else
{
// 不会到这里
}
return nN;
}
int main()
{
int nX = 0, nY = 0;
//std::cout << "0 : (" << nX << ", " << nY << ")" << std::endl;
int K = 5;
for (int i = 1; i < (2*K+1)*(2*K+1); i++)
{
// 第一种算法
RingSearch_Next(nX, nY);
// 第二种算法
int nX2, nY2;
RingSearch_Index(i, nX2, nY2);
if (nX != nX2 || nY != nY2)
{
std::cout << "Error" << std::endl;
}
// 反向计算序号
int iii = GetRingIndex(nX, nY);
if (i != iii)
{
std::cout << "Error" << std::endl;
}
print((nX2 + 10) * 3, (nY2 + 10) * 3, std::to_string(i));
//std::cout <<i << " : (" << nX << ", " << nY << ")" << std::endl;
}
return 0;
}