枚举求解
货真价实的2星题目,并未用到多难的算法,考验的是做题者的基本功
唯一的难点就在于判定”碰壁“和”碰壁“时如何改变运动状态。为了避免边界问题我初始化了每个点的状态,然后改变经过点的状态来判断这个点是否到达过。
代码如下:
#include <bits/stdc++.h> using namespace std; const int N = 2010; const int F = -1; int a[N][N]; int f[N][N];//记录已通过点的状态 int m, n; int fx[N] = {0, 0, 1, 0, -1}; int fy[N] = {0, 1, 0, -1, 0}; //进行坐标x,y的上下左右移动; int main() { cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { cin >> a[i][j]; f[i][j] = 0;//初始化每个点状态 0为未通过 }//录入矩阵 long long sum1 = 0, sum2 = 0; int cnt = 1, s = 1;//cnt为当前已经过的点,s为当前运动状态 int x = 1, y = 1;//由第一行第一列的点开始枚举 while (cnt <= m * n) { f[x][y] = 1;//改变点状态,记录为已经过 int tx = x, ty = y; if (cnt % 2 != 0) sum1 += a[x][y]; else sum2 += a[x][y]; switch (s % 4) { case 1: tx = x, ty = y; tx += fx[1]; ty += fy[1]; if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && f[tx][ty] == 0) break; else s++; case 2: tx = x, ty = y; tx += fx[2]; ty += fy[2]; if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && f[tx][ty] == 0) break; else s++; case 3: tx = x, ty = y; tx += fx[3]; ty += fy[3]; if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && f[tx][ty] == 0) break; else s++; case 0: tx = x, ty = y; tx += fx[4]; ty += fy[4]; if (tx >= 1 && tx <= n && ty >= 1 && ty <= m && f[tx][ty] == 0) break; else { tx = x, ty = y; tx += fx[1]; ty += fy[1]; s++; } break; } x = tx; y = ty; cnt++; } if (n == 1 && m == 1) cout << sum1 << endl << F;//没有偶数项 else cout << sum1 << endl << sum2; }代码中难理解的或许是switch中的内容,其实本质就是判断若继续当前运动状态,到达的下一个点(tx,ty)是否合法,若合法则break,若不合法则跳入下一个case。
这时候我们提前预设fx,fy的好处就体现了,回型运动的方向是右下左上,我们设置的顺序正好也是右下左上(一般都这样设置),在向右运动不合法是跳入向下运动的case,同时更新运动状态s,向下,向左不合法同类。
注:学校内比赛给学弟学妹写的题解,用的最简单的方法,有大佬觉得方法笨勿喷