The first line of the input gives the number of test cases, T. T test cases follow. Each test case consists of S which is the side length of the square maze. Then S2 numbers follow like a maze to give the numbers that have been assigned to the rooms.
1 2 9 5 3 8 4 6 7
For each test case, output one line containing "Case #x: r d", where x is the test case number (starting from 1), r is the room number of the person who will win and d is the number of rooms he could move. In case there are multiple such people, the person who is in the smallest room will win.
1 ≤ T ≤ 100.
1 ≤ S ≤ 10
1 ≤ S ≤ 103.
类型:图论 dp 难度:2
题意:给出一个s*s的图,图中每个格子分别包含从1到s*s的数字。每个格子中有一个人,若相邻的四个格子中的数字有当前数字+1,那么人可以走到这个相邻的格子中。求能走的路径最长的格子内的数字,以及最长路径长度。若多个数字的长度相同,取最小的数字。
分析:google的这次Round D题难度都不高。这个题使用bfs加dp即可解决。用mz[i][j]记录点(i,j)的数字,用len[i][j]记录点(i,j)的路径长度。
那么,对每个点,len[i][j] = len[ni][nj] + 1,(ni,nj)为(i,j)的邻点,且满足mz[ni][nj] = mz[i][j]+1;若没有满足条件的邻点,len[i][j] = 1
遍历图中所有的点,记录结果。
代码:
#include <iostream> #include <vector> #include <algorithm> #include <cstdint> #include <cstdio> #include <cstring> #include <string> using namespace std; const int N = 1010; int s; int mz[N][N],len[N][N]; int maxn,maxl; int fun(int i, int j) { if(len[i][j] > 0) return len[i][j]; int nown = mz[i][j]; int nowl = 0; if(i>0 && nown+1==mz[i-1][j]) nowl = max(nowl,fun(i-1,j)); if(i<s-1 && nown+1==mz[i+1][j]) nowl = max(nowl,fun(i+1,j)); if(j>0 && nown+1==mz[i][j-1]) nowl = max(nowl,fun(i,j-1)); if(j<s-1 && nown+1==mz[i][j+1]) nowl = max(nowl,fun(i,j+1)); ++nowl; len[i][j] = nowl; return nowl; } int main() { freopen("A-large.in", "r", stdin); freopen("A-large.out", "w", stdout); int t; scanf("%d",&t); for(int cnt=1; cnt<=t; ++cnt) { scanf("%d",&s); for(int i=0; i<s; ++i) for(int j=0; j<s; ++j) scanf("%d",&mz[i][j]); memset(len,0,sizeof(len)); maxn = 1; maxl = 1; for(int i=0; i<s; ++i) for(int j=0; j<s; ++j) { int nowl = fun(i,j); if(nowl>maxl || (nowl==maxl && mz[i][j]<maxn)) { maxn = mz[i][j]; maxl = nowl; } } printf("Case #%d: %d %d\n",cnt,maxn,maxl); } }