斜对角线的应用

引入

题目描述

经典应用:八皇后问题

dg和udg数组的解释

image

对角线 \(dg[u+i]dg[u+i]\),反对角线\(udg[n−u+i]udg[n−u+i]\)中的下标 \(u+i\)\(n−u+i\) 表示的是截距
下面分析中的 \((x,y)\) 相当于上面的 \((u,i)\)
反对角线 \(y=x+b\), 截距 \(b=y−x\),因为我们要把 \(b\) 当做数组下标来用,显然 \(b\) 不能是负的,所以我们加上 \(+n\) (实际上 \(+n+4\) , \(+2n\)都 行),来保证是结果是正的,即 \(y-x+n\)
而对角线 \(y=−x+b\), 截距是 \(b=y+x\),这里截距一定是非负的,所以不需要加偏移量
核心目的:找一些合法的下标来表示dgdg或udg是否被标记过,所以如果你愿意,你取 \(udg[n+n−u+i]\) 也可以,只要所有 \((u,i)\) 对可以映射过去就行

代码

#include <iostream>

using namespace std;

const int N = 20;

int n;
char g[N][N];
bool col[N], dg[N], udg[N];

void dfs(int u)
{
    if (u == n)
    {
        for (int i = 0; i < n; i ++ ) puts(g[i]);
        puts("");
        return;
    }

    for (int i = 0; i < n; i ++ )
        if (!col[i] && !dg[u + i] && !udg[n - u + i])
        {
            g[u][i] = 'Q';
            col[i] = dg[u + i] = udg[n - u + i] = true;
            dfs(u + 1);
            col[i] = dg[u + i] = udg[n - u + i] = false;
            g[u][i] = '.';
        }
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            g[i][j] = '.';

    dfs(0);

    return 0;
}

例题

题目表述

Codeforce

代码

#include <iostream>
#include <cstring>
#include <algorithm>

#define x first
#define y second

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 410;

int T, n, m;
int a[N][N];
int l[N], r[N];

int main()
{
	cin >> T;
	while(T -- )
	{
		memset(l, 0, sizeof l);
		memset(r, 0, sizeof r);
		
		cin >> n >> m;
		for(int i = 0; i < n; i ++ )
			for(int j = 0; j < m; j ++ )
			{
				cin >> a[i][j];
				l[i + j] += a[i][j];
				r[j - i + n] += a[i][j];
			}
		
		int res = -1;
		for(int i = 0; i < n; i ++ )
			for(int j = 0; j < m; j ++ )
			{
				//注意枚举到的枚举加了两次,还需要减去一次 
				res = max(res, l[i + j] + r[j - i + n] - a[i][j]);
			}

		cout << res << endl;
		
	}   
	 
    return 0;
}
posted @ 2022-05-11 09:44  光風霽月  阅读(71)  评论(0编辑  收藏  举报