Google中国2015校园招聘笔试Round D APAC Test Problem A. Cube IV

Problem

Vincenzo decides to make cube IV but only has the budget to make a square maze. Its a perfect maze, every room is in the form of a square and there are 4 doors (1 on each side of the room). There is a big number written in the room. A person can only move from one room to another if the number in the next room is larger than the number in his current room by 1. Now, Vincenzo assigns unique numbers to all the rooms (1, 2, 3, .... S 2 ) and then places S 2  people in the maze, 1 in each room where S is the side length of the maze. The person who can move maximum number of times will win. Figure out who will emerge as the winner and the number of rooms he will be able to move.

Input

The first line of the input gives the number of test cases, TT 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 

Output

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.

Limits

1 ≤ T ≤ 100.

Small dataset

1 ≤ S ≤ 10

Large dataset

1 ≤ S ≤ 103.

Sample


Input 
 

Output 
 
2
2
3 4
1 2 


3
1 2 9 
5 3 8 
4 6 7 
Case #1: 1 2
Case #2: 6 4

类型:图论 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);
    }
}


你可能感兴趣的:(C++,dp,Google,图论,笔试)