- 论坛徽章:
- 0
|
- #include <iostream>
- #include <vector>
- #include <cmath>
- #include <iomanip>
- #include <cassert>
- using namespace std;
- void MagicSquare_DoubleEven(int n);
- void MagicSquare_SingleEven(int n);
- void MagicSquare_Odd(int n);
- int Mode(int Nbr, int Mod);
- class cell
- {
- public:
- int Nbr;
- bool Is_Empty;
- };
- class unit
- {
- public:
- int Nbr;
- char tag;
- bool Is_Empty;
- };
- int main()
- {
- cout << "Input the number of row" << endl;
- int n;
- cin >> n;
- if (n <= 0)
- {
- cerr << "Invalid because " << n << " <= 0" << endl;
- exit(1);
- }
- else if(n % 2 == 1)
- MagicSquare_Odd(n);
-
- else if (n % 4 == 0)
- MagicSquare_DoubleEven(n);
- else
- MagicSquare_SingleEven(n);
-
- return 0;
- }
- void MagicSquare_DoubleEven(int n)
- {
- vector< vector<int> > Square(n);
- int r, c, value = 1;
-
- for (r = 0; r < n; ++r)
- {
- Square[r].resize(n);
- for (c = 0; c < n; ++c, ++value)
- {
- Square[r][c] = value;
- }
- }
- int m = n/4;
- int i, j;
- int rd = 0;
- int cd = 0;
- for (i = 0; i < m; ++i)
- {
- for (j = 0; j < m; ++j)
- {
- rd = (i-0)*4;
- cd = (j-0)*4;
- for (r = rd; r<rd+4; ++r)
- for (c = cd; c<cd+4; ++c)
- if ((r-rd == c-cd) || (r-rd+c-cd==3))
- Square[r][c] = n*n+1-Square[r][c];
- }
- }
- for (r = 0; r < n; ++r)
- {
- for (c = 0; c < n; ++c)
- {
- cout << setw(3) << Square[r][c] << " ";
- }
- cout << endl;
- }
- }
- void MagicSquare_SingleEven(int n)
- {
- int m = (n-2)/4;
- vector< vector<unit> > LUX(2*m+1);
- unit Inlitial = {0, 'L', true};
- int i;
- for (i = 0; i < m+1; ++i)
- LUX[i].resize(2*m+1,Inlitial);
- Inlitial.tag = 'U';
- LUX[i].resize(2*m+1,Inlitial);
- Inlitial.tag = 'X';
- for (i = m+2; i < 2*m+1; ++i)
- LUX[i].resize(2*m+1, Inlitial);
-
- char ctemp = LUX[m][m].tag;
- LUX[m][m].tag = LUX[m+1][m].tag;
- LUX[m+1][m].tag = ctemp;
- int r;
- vector< vector<int> > Square(n);
- for (r = 0; r < n; ++r)
- Square[r].resize(n, 0);
-
- // much like MagicSquare_Odd
- r = 0;
- int c = m;
- int tem_r, tem_c;
- int value = 1;
- LUX[r][c].Nbr = 1;
- LUX[r][c].Is_Empty = false;
-
- Square[2*r][2*c+1] = value++;
- Square[2*r+1][2*c] = value++;
- Square[2*r+1][2*c+1] = value++;
- Square[2*r][2*c] = value++;
- for (int step = 2; step < (2*m+1)*(2*m+1)+1; ++step)
- {
- tem_r = Mode(r-1, 2*m+1);
- tem_c = Mode(c+1, 2*m+1);
- if (LUX[tem_r][tem_c].Is_Empty)
- {
- LUX[tem_r][tem_c].Nbr = step;
- LUX[tem_r][tem_c].Is_Empty = false;
- r = tem_r;
- c = tem_c;
- }
-
- else
- {
- r = Mode(r+1, 2*m+1);
- LUX[r][c].Nbr = step;
- LUX[r][c].Is_Empty = false;
- }
- ctemp = LUX[r][c].tag;
- switch(ctemp)
- {
- case 'L':
- Square[2*r][2*c+1] = value++;
- Square[2*r+1][2*c] = value++;
- Square[2*r+1][2*c+1] = value++;
- Square[2*r][2*c] = value++;
- break;
- case 'U':
- Square[2*r][2*c] = value++;
- Square[2*r+1][2*c] = value++;
- Square[2*r+1][2*c+1] = value++;
- Square[2*r][2*c+1] = value++;
- break;
- case 'X':
- Square[2*r][2*c] = value++;
- Square[2*r+1][2*c+1] = value++;
- Square[2*r+1][2*c] = value++;
- Square[2*r][2*c+1] = value++;
- break;
- default:
- cerr << "There is something wrong" << endl;
- exit(1);
- }
- }
- for (r = 0; r < n; ++r)
- {
- for (c = 0; c < n; ++c)
- {
- cout << setw(3) << Square[r][c] << " ";
- }
- cout << endl;
- }
- }
- void MagicSquare_Odd(int n)
- {
- vector< vector<cell> > Square(n);
- cell Inlitial = {0, true};
- int r;
- for (r = 0; r < Square.size(); ++r)
- Square[r].resize(n, Inlitial);
- r = 0;
- int c = (n-1)/2;
- int tem_r, tem_c;
- Square[r][c].Nbr = 1;
- Square[r][c].Is_Empty = false;
- for (int step = 2; step < n*n+1; ++step)
- {
- tem_r = Mode(r-1, n);
- tem_c = Mode(c+1, n); // difference
- if (Square[tem_r][tem_c].Is_Empty)
- {
- Square[tem_r][tem_c].Nbr = step;
- Square[tem_r][tem_c].Is_Empty = false;
- r = tem_r;
- c = tem_c;
- }
-
- else
- {
- r = Mode(r+1, n);
- Square[r][c].Nbr = step;
- Square[r][c].Is_Empty = false;
- }
- }
- for (r = 0; r < Square.size(); ++r)
- {
- for (c = 0; c < Square.size(); ++c)
- {
- cout << setw(3) << Square[r][c].Nbr << " ";
- }
- cout << endl;
- }
- }
- int Mode(int Nbr, int Mod)
- {
- assert(Mod);
- int tem = abs(Nbr);
- tem /= Mod;
- if (Nbr >= 0)
- Nbr = Nbr % Mod;
-
- else
- Nbr = Nbr + (tem+1)*Mod;
- return Nbr;
- }
复制代码 |
|