言琢დ @ 2024-01-05 13:08:03
RT
感觉按照题目要求的范围数组开得足够大了但还是过不掉,不清楚是什么原因。
#include<cstdio>
#include<cstring>
int init(){
char c = getchar();
int x = 0, f = 1;
for (; c < '0' || c > '9'; c = getchar())
if (c == '-') f = -1;
for (; c >= '0' && c <= '9'; c = getchar())
x = (x << 1) + (x << 3) + (c ^ 48);
return x * f;
}
void print(int x){
if (x < 0) x = -x, putchar('-');
if (x > 9) print(x / 10);
putchar(x % 10 + '0');
}
const int N = (int) 1e3 + 5; // 这里如果改成 1e2 + 5 就会有 2 个点 WA
int n, m, a[N][N], du[N * N], q[N * N];
struct Node{
int next, to;
} s[N * N]; int head[N * N], sLen;
void add(int u, int v){
s[++sLen].next = head[u];
s[sLen].to = v;
head[u] = sLen;
++du[v];
}
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};
bool ok(int x, int y){
return x >= 1 && y >= 1 && x <= n && y <= m;
}
int node(int x, int y){
return (x-1) * m + y;
}
int mx(int x, int y){
return x > y ? x : y;
}
int dp[N * N];
int main(){
n = init(), m = init();
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
a[i][j] = init();
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
for (int k = 0; k < 4; ++k) {
int ni = i + dx[k], nj = j + dy[k];
if (ok(ni, nj) && a[i][j] > a[ni][nj])
add(node(i, j), node(ni, nj));
}
for (int i = 1; i <= n * m; ++i)
if (!du[i]) dp[q[++q[0]] = i] = 1;
int nxt = 1, ans = 1;
while (nxt <= q[0]) {
int u = q[nxt++];
for (int i = head[u]; i; i = s[i].next) {
int v = s[i].to;
ans = mx(ans, dp[v] = mx(dp[v], dp[u] + 1));
if (!--du[v]) q[++q[0]] = v;
}
}
print(ans), putchar('\n');
}
by 言琢დ @ 2024-01-05 13:09:08
怀疑可能是数组 assert
发现 q[0] <= n * m
并不成立。
但我寻思着这种有向无环图按道理每个点只能进队一次吧,为啥不满足这个性质,不太懂哦