G 九峰与蛇形填数
思路
这个题目直接暴力就可以了,不需要用啥线段树。
每个点每次取值肯定是最后一个覆盖到它区域的值,所以直接取那个数即可。
然后还有一个细节就是剪枝,预处理区域的大小,如果这个点不在这个区域直接break。不用赋值了。
AC代码
#include<bits/stdc++.h>
using namespace std;
#define _for(i, a, b) for (int i = (a); i < (b); ++i)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define For(i, a, b) for (int i = (a); i >= (b); --i)
#define mod(x) (x) % MOD
#define debug(a) cout << #a << " = " << a << endl;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int N = 3000 + 10, M = 2010, INF = 0x3f3f3f3f;
int n, m;
int x[N], y[N], k[N],g[M][M];
bool inside(int t, int a, int b)
{
return a <= t && t <= b;
}
int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
#endif
ios::sync_with_stdio(false);
cout.tie(0);
cin.tie(0);
cin >> n >> m;
int x1 = INF, y1 = INF, x2 = 0, y2 = 0;
_rep(i, 1, m)
{
cin >> x[i] >> y[i] >> k[i];
x1 = min(x1, x[i]);
y1 = min(y1, y[i]);
x2 = max(x2, x[i] + k[i] - 1);
y2 = max(y2, y[i] + k[i] - 1);
}
_rep(i, 1, n) _rep(j, 1, n) For(l, m, 1)
{
if (!inside(i, x1, x2) || !inside(j, y1, y2)) break;
if (inside(i, x[l], x[l] + k[l] - 1) && inside(j, y[l], y[l] + k[l] - 1))
{
g[i][j] = k[l] * (i - x[l]);
if (i - x[l] & 1) g[i][j] += y[l] + k[l] - j;
else g[i][j] += j - y[l] + 1;
break;
}
}
_rep(i, 1, n) _rep(j, 1, n) printf("%d%s", g[i][j], j == n ? "\n" : " ");
return 0;
} 
京公网安备 11010502036488号