1. 程式人生 > 實用技巧 >2019 ICPC NanJing C Digital Path

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\n", (res + mod) % mod);
}

心結了了。