Luo Gu P1549 chessboard (2)

Luo Gu P1549 chessboard (2)

topic:

  • There are pictures, transfer link

answer:

  • Seeing this is a title search Well Road (also said to be hand-counted). But I guess a normal burst search will certainly timeout, so we have to find out where pruning. RT, both the number and prime number! ? The mathematical analysis, must be odd primes, because even-numbered 2 may be divisible. + = Even number and odd odd. Therefore, the n * n is an odd square certainly put such an even number. like this:

  • Parity Parity ...

    Even parity Odd ...

    Parity Parity ...

  • Observation, that the coordinates are the same odd odd or even, for example, (1, 1) (1, 3) (2, 2) (2, 4). While the remaining cases is even. So we can be judged according to the coordinates of the points in the end to fill even or odd. So as to achieve the effect of pruning

  • As a prime number is determined with a sieve like a ... Euler

  • Remember special judge about the case n = 1

#include <iostream>
#include <cstdio>
#define maxn 15 * 15
#define inf 0x7fffffff
using namespace std;

int n, cnt, minn = inf, pos;
int a[maxn][maxn], ans[maxn][maxn];
int pri[maxn];
bool vis[maxn], flag[maxn] = {1, 1};

bool cal(int x, int y, int num)
{
    if(a[x - 1][y] != 0)
        if(flag[a[x - 1][y] + num])
            return 0;
    if(a[x + 1][y] != 0)
        if(flag[a[x + 1][y] + num])
            return 0;
    if(a[x][y - 1] != 0)
        if(flag[a[x][y - 1] + num])
            return 0;
    if(a[x][y + 1] != 0)
        if(flag[a[x][y + 1] + num])
            return 0;
    return 1;
}

void dfs(int x, int y, int step, int sum)
{
    if(sum >= minn) return;
    if(step > n * n)
    {
        pos = 1;
        minn = sum;
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                ans[i][j] = a[i][j];
        return;
    }
    if((x % 2 != 0 && y % 2 != 0) || (x % 2 == 0 && y % 2 == 0))
    {
        for(int i = 3; i <= n * n; i += 2)
            if(!vis[i] && cal(x, y, i))
            {
                vis[i] = 1;
                a[x][y] = i;
                int summ = sum;
                if(y == 1 || x == 1) summ += i;
                if(y + 1 > n) dfs(x + 1, 1, step + 1, summ);
                else dfs(x, y + 1, step + 1, summ);
                vis[i] = 0;
                a[x][y] = 0;
            }
    }
    else
    {
        for(int i = 2; i <= n * n; i += 2)
            if(!vis[i] && cal(x, y, i))
            {
                vis[i] = 1;
                a[x][y] = i;
                int summ = sum;
                if(y == 1 || x == 1) summ += i;
                if(y + 1 > n) dfs(x + 1, 1, step + 1, summ);
                else dfs(x, y + 1, step + 1, summ);
                vis[i] = 0;
                a[x][y] = 0;
            }
    }
}

int main()
{
    for(int i = 2; i <= 100; i++)
    {
        if(!flag[i]) pri[++cnt] = i;
        for(int j = 1; j <= cnt && pri[j] * i <= 100; j++)
        {
            flag[i * pri[j]] = 1;
            if(i % pri[j] == 0) break;
        }
    }
    cin >> n;
    if(n == 1) {cout << "NO"; return 0;}
    vis[1] = 1, a[1][1] = 1;
    dfs(1, 2, 2, 1);
    if(!pos) cout << "NO";
    else
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= n; j++)
                cout << ans[i][j] << ' ';
            cout << endl;
        }
    return 0;
}

Guess you like

Origin www.cnblogs.com/BigYellowDog/p/11129787.html