斜对角线的应用
引入
题目描述
dg和udg数组的解释
对角线 \(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;
}
例题
题目表述
代码
#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;
}