|
发表于 2021-5-7 13:01:47
|
显示全部楼层
本帖最后由 yuxijian2020 于 2021-5-7 15:18 编辑
- #include <iostream>
- #include <vector>
- using namespace std;
- struct Point
- {
- int x;
- int y;
- Point() : x(0), y(0) {}
- Point(int x, int y) : x(x), y(y) {}
- };
- class MagicSquare
- {
- public:
- MagicSquare() = delete;
- MagicSquare(MagicSquare&) = delete;
- MagicSquare(MagicSquare&&) = delete;
- explicit MagicSquare(int len) : len(len)
- {
- CreateSquare();
- }
- ~MagicSquare()
- {
- if (judgeArr)
- delete[] judgeArr;
- if (square)
- delete[] square;
- len = 0;
- }
- void PrintSquare()
- {
- for (int i = 0; i < len; ++i)
- {
- for (int j = 0; j < len; j++)
- {
- printf_s("%3d ", square[i * len + j]);
- }
- printf_s("\n");
- }
- }
- int GetNumberByPoint(Point p) { return square[p.x * len + p.y]; }
- private:
- void CreateSquare()
- {
- square = new int[len * len * sizeof(int)];
- memset(square, 0, len * len * sizeof(int));
- judgeArr = new int[len * len * sizeof(int)];
- memset(judgeArr, 0, len * len * sizeof(int));
- //w 列 h 行
- int w = len / 2, h = 0;
- //已经填充的数量
- int total = 0;
- //填充数字
- int num = 1;
- while (total < len * len)
- {
- square[h * len + w] = num;
- judgeArr[h * len + w] = 1;
- int prevW = w;
- int prevH = h;
- h--;
- w++;
- total++;
- num++;
- //下个位置已经填过值 或 超出范围
- while (w >= len || h < 0 || judgeArr[h * len + w] == 1)
- {
- int time = 0;
- if (w >= len)
- w = 0;
- if (h < 0)
- h = len - 1;
- if (judgeArr[h * len + w] == 1)
- {
- //回溯
- w = prevW;
- h = prevH;
-
- if (time == 0)
- h++;
- else
- {
- h--, w++;
- }
- prevW = w;
- prevH = h;
- time++;
- }
- }
- }
- }
- //幻方边长
- int len;
- //幻方
- int* square;
- //判断当前位置是否已经存在值的数组
- int* judgeArr;
- };
- vector<int> GetInputAndResult()
- {
- int len = 0, sum = 0;
-
- while (len % 2 == 0 || sum > len * len)
- {
- printf_s("请输入幻方阶数(奇数)和被污染的格子数:");
- scanf_s("%d%*c%d%*c", &len, &sum);
-
- if (len % 2 == 0)
- {
- printf_s("幻方的阶数必须为奇数!\n");
- continue;
- }
- if (sum > len * len)
- {
- printf_s("被污染的格子数超过了总格子数!\n");
- continue;
- }
- }
- MagicSquare ms(len);
- Point p;
- vector<int> result;
- for (int i = 0; i < sum; ++i)
- {
- printf("请输入第 %d 个被污染的格子坐标:", i + 1);
- scanf_s("%d%*c%d%*c", &p.x, &p.y);
- //坐标超出范围
- if ((p.x < 1 || p.x > len) && (p.y < 1 || p.y > len))
- {
- i--;
- continue;
- }
- p.x--, p.y--;
- result.push_back(ms.GetNumberByPoint(p));
- }
- return result;
- }
- int main()
- {
- vector<int> result(GetInputAndResult());
- for (const auto& i : result) { printf_s("%d\n", i); }
- return 0;
- }
复制代码 |
|