枚举求解
货真价实的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,向下,向左不合法同类。
注:学校内比赛给学弟学妹写的题解,用的最简单的方法,有大佬觉得方法笨勿喷