2019 ICPC NanJing C Digital Path

C. Digital Path

题意:

给一个二维数组,问连续差值为1的序列数目

当时比赛想的是 (BFS) , 还搞了个多源 (BFS)

但是没有办法做到每个点只访问一次。

其实这道题应该使用 (DFS) 进行回溯

更新答案。

思路:

对于这个长度至少为4的处理,一开始还是处理的有些不妥。

后来直接多开了一维记录长度,简单的一批。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 1e3 + 10;
int A[maxn][maxn];
int vis[maxn][maxn];
ll ans[maxn][maxn][5];


const int dx[] = { 0,0,-1,1 };
const int dy[] = { 1,-1,0,0 };

const int mod = 1e9 + 7;

int n, m;

void dfs(int x, int y) {
	vis[x][y] = 1;
	int cnt = 0;
	for (int i = 0; i < 4; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		if (nx <= 0 || nx > n || ny <= 0 || ny > m)continue;
		if (A[nx][ny] != A[x][y] + 1)continue;

		cnt++;
		if (!vis[nx][ny]) {
			dfs(nx, ny);
		}
		ans[x][y][2] = (ans[nx][ny][1] + ans[x][y][2]) % mod;
		ans[x][y][3] = (ans[nx][ny][2] + ans[x][y][3]) % mod;
		ans[x][y][4] = (ans[nx][ny][3] + ans[x][y][4] + ans[nx][ny][4]) % mod;
	}
	if (!cnt) {
		ans[x][y][1] = 1;
	}
}

int main() {
	scanf("%d%d", &n, &m);

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			scanf("%d", &A[i][j]);
		}
	}

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			if (!vis[i][j])dfs(i, j);
		}
	}

	long long res = 0;

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			int f = 0;

			for (int k = 0; k < 4; k++) {
				int x = i + dx[k];
				int y = j + dy[k];
				if (x <= 0 || x > n || y <= 0 || y > m)continue;
				if (A[x][y] == A[i][j] - 1) {
					f = 1;
					break;
				}
			}

			if (!f) {
				res = (res + ans[i][j][4]) % mod;
			}
		}
	}

	printf("%lld
", (res + mod) % mod);
}

心结了了。

原文地址:https://www.cnblogs.com/sduwh/p/13693186.html