Description
The cows have revised their game of leapcow. They now play in the middle of a huge pasture upon which they have marked a grid that bears a remarkable resemblance to a chessboard of N rows and N columns (3 <= N <= 365).
Here‘s how they set up the board for the new leapcow game:
* First, the cows obtain N x N squares of paper. They write the integers from 1 through N x N, one number on each piece of paper.
* Second, the ‘number cow‘ places the papers on the N x N squares in an order of her choosing.
Each of the remaining cows then tries to maximize her score in the game.
* First, she chooses a starting square and notes its number.
* Then, she makes a ‘knight‘ move (like the knight on a chess board) to a square with a higher number. If she‘s particularly strong, she leaps to the that square; otherwise she walks.
* She continues to make ‘knight‘ moves to higher numbered squares until no more moves are possible.
Each square visited by the ‘knight‘ earns the competitor a single point. The cow with the most points wins the game.
Help the cows figure out the best possible way to play the game.
Input
* Line 1: A single integer: the size of the board
* Lines 2.. ...: These lines contain space-separated integers that tell the contents of the chessboard. The first set of lines (starting at the second line of the input file) represents the first row on the chessboard; the next set of lines represents the next row, and so on. To keep the input lines of reasonable length, when N > 15, a row is broken into successive lines of 15 numbers and a potentially shorter line to finish up a row. Each new row begins on its own line.
Output
* Line 1: A single integer that is the winning cow‘s score; call it W.
* Lines 2..W+1: Output, one per line, the integers that are the starting square, the next square the winning cow visits, and so on through the last square. If a winning cow can choose more than one path, show the path that would be the ‘smallest‘ if the paths were sorted by comparing their respective ‘square numbers‘.
Sample Input
4 1 3 2 16 4 10 6 7 8 11 5 12 9 13 14 15
Sample Output
7 2 4 5 9 10 12 13 题意:给你一个矩阵,问你按照象棋马的走法,下一步比上一步的数大,问长度最长的序列是多长,然后输出序列。如果有多个最长序列输出字典序最小的那个。这是看到的一个代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <vector> 6 #include <algorithm> 7 #include <map> 8 using namespace std; 9 typedef pair<int,int>P; 10 const double eps=1e-9; 11 const int maxn=200100; 12 const int mod=1e9+7; 13 const int INF=1e9; 14 int M[370][370],dp[370][370]; 15 int N; 16 int dx[8]= {1,1,2,2,-1,-1,-2,-2}; 17 int dy[8]= {2,-2,1,-1,2,-2,1,-1}; 18 P path[370][370]; 19 vector<P>res; 20 int DP(int x,int y) 21 { 22 int &m=dp[x][y]; 23 if(m) return m; 24 m=1; 25 for(int i=0; i<8; i++) 26 { 27 int nx=x+dx[i]; 28 int ny=y+dy[i]; 29 if(1<=nx&&nx<=N&&1<=ny&&ny<=N&&M[nx][ny]>M[x][y]) 30 { 31 if(m<DP(nx,ny)+1) 32 { 33 m=DP(nx,ny)+1; 34 path[x][y]=make_pair(nx,ny); 35 } 36 else if(DP(nx,ny)+1==m) 37 { 38 if(M[path[x][y].first][path[x][y].second]>M[nx][ny]) 39 { 40 path[x][y]=make_pair(nx,ny); 41 } 42 } 43 } 44 } 45 return m; 46 } 47 int main() 48 { 49 while(~scanf("%d",&N)) 50 { 51 for(int i=1; i<=N; i++) 52 { 53 for(int j=1; j<=N; j++) 54 { 55 scanf("%d",&M[i][j]); 56 } 57 } 58 int MAX=1,cnt; 59 for(int i=1; i<=N; i++) 60 { 61 for(int j=1; j<=N; j++) 62 { 63 cnt=DP(i,j); 64 if(MAX<cnt) 65 { 66 MAX=cnt; 67 res.clear(); 68 res.push_back(make_pair(i,j)); 69 } 70 else if(MAX==cnt) 71 { 72 res.push_back(make_pair(i,j)); 73 } 74 } 75 } 76 int keyx,keyy,key; 77 key=INF; 78 for(int i=0; i<res.size(); i++) 79 if(M[res[i].first][res[i].second]<key) 80 { 81 key=M[res[i].first][res[i].second]; 82 keyx=res[i].first; 83 keyy=res[i].second; 84 } 85 printf("%d\n",MAX); 86 while(1) 87 { 88 printf("%d\n",M[keyx][keyy]); 89 int t=path[keyx][keyy].second; 90 keyx=path[keyx][keyy].first; 91 keyy=t; 92 if(!keyx) 93 break; 94 } 95 } 96 return 0; 97 }
知识点:
这个代码的主要想法是,如同最短路一样,path中储存的是当前节点的下一步应该走的位置,然后进行搜索直到遍历了所有的点。