大d的考题 找规律

大d的考题

题意:给定一个N*N的矩阵,里面放置1,2,3...N*N这N*N个数,要求是第i个数的行和第i-1个数的列必须相同。问1所在的行的和值与N*N所在列的和值之差最小是多少。

解法:通过dfs搜索得到1,2,3,4对应的解分别为0,2,6,12,当N=5的时数据规模已经庞大到无法在有限时间内得到结果了,根据这几组结果推断结果为ans = (N-1)*(N)。提交AC。

代码如下:

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;

const int INF = ~(1<<31);
const int MaxN = 4005;
int N, Min, lim;
int cc, rr;
short vis[MaxN*MaxN];

void dfs(int x, int p) {
    int c, r = p % N; // 当前列和上一个数字的行相同
    int np;
    if (x == N*N) {
        cc = p % N;
        int sumc = 0, sumr = 0;
        for (int i = 0; i < N; ++i) {
            sumr += vis[rr*N+i];
            sumc += vis[i*N+cc];
        }
        Min = min(Min, abs(sumc-sumr));
    }
    for (c = 0; c < N; ++c) {
        np = r * N + c;
        if (!vis[np]) {
            vis[np] = x+1;
            dfs(x+1, np);
            vis[np] = 0;
        }
    }
}

int main() {
    memset(vis, 0, sizeof (vis));
    while (scanf("%d", &N) != EOF) {
        Min = INF;
        lim = N * N;
    /*    for (int i = 0; i < lim; ++i) {
            rr = i / N; // 记录1所在位置的行号
            vis[i] = 1; // i位置被1占据
            dfs(1, i);
            vis[i] = 0; // 回溯
        }*/
        printf("%d\n", (N-1)*N);
    }
    return 0;    
}
原文地址:https://www.cnblogs.com/Lyush/p/2979342.html