题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4708
题意:给一个奇数边长的正方形,每一层可以顺时针或逆时针旋转,求能够得到的主对角线和副对角线的总和最大(中心只算一次),以及旋转的最小次数之和。
思路:模拟。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
#define MAX 100000000
int a[10][10];
int main()
{
int n;
while(cin>>n,n){
int num=0,ans = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin>>a[i][j];
}
}
int x1,y1,x2,x3,x4,y2,y3,y4;
int tmp = 0,tt = 0,mm = 0,nu = 0;
for (int k = 0; k < n/2; k++)//只转n/2层
{
nu = tt = 0; mm = tmp = -MAX;
x1 = y1 = k;//两对角线的四个顶点坐标
x2 = k,y2 = n-k-1;
x3 = y3 = n-k-1;
x4 = n-k-1,y4 = k;
tmp = a[x1][y1]+a[x2][y2]+a[x3][y3]+a[x4][y4];
mm = tmp;
for (int j = 0; j < (n-k*2)-2; j++)//每层变换(n-k*2)-2次。
{
nu++;
y1++;x2++;y3--;x4--;//旋转的变换
tmp = a[x1][y1]+a[x2][y2]+a[x3][y3]+a[x4][y4];
if(tmp>mm)
{
mm = tmp;
tt = nu>(n-2*k-1-nu)?(n-2*k-1-nu):nu;//顺时针和逆时针,判断大小
}else if(tmp == mm){//要最小的旋转次数,容易错!
int tx = nu>(n-2*k-1-nu)?(n-2*k-1-nu):nu;
tt = tt<tx?tt:tx;
}
}
ans += mm;
num += tt;
}
ans += a[n/2][n/2];
printf("%d %d\n",ans,num);
}
return 0;
}