2013杭电warm up1 Rotation Lock Puzzle

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4708

首先来学习一个ac的代码:

作者 http://blog.csdn.net/xingyeyongheng

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<iomanip>
#define INF 99999999
using namespace std;

const int MAX=10;
int s[MAX][MAX];

int main(){
	int n;
	while(scanf("%d",&n),n){
		for(int i=0;i<n;++i){
			for(int j=0;j<n;++j)scanf("%d",&s[i][j]);
		}
		int sum=0,num=0,temp=0,k; 
		for(int i=0;i<n/2;++i){//从第i行开始的四边形 
			k=0,temp=-INF;
			for(int j=0;j<=n-2*i-2;++j){//分别计算顺时针旋转j(逆时针旋转n-2*i-1-j次)次后左上角,左下角,右上角,右下角相加的和 
				if(s[i+j][i]+s[n-1-i][i+j]+s[i][n-1-i-j]+s[n-1-i-j][n-1-i]>temp){
					temp=s[i+j][i]+s[n-1-i][i+j]+s[i][n-1-i-j]+s[n-1-i-j][n-1-i];
					k=j;
				}
			}
			sum+=temp;
			num+=min(k,n-2*i-1-k);
		}
		cout<<sum+s[n/2][n/2]<<' '<<num<<endl;
	}
	return 0;
}

这个能ac ,但是思路有所欠缺,数据严格一些就会wa  因为只考虑了顺时针转,如果再转一次使min(k,n-1-2*i-k) 更小,然而temp值相等(不满足>) k就不会更新。

但是sum算得是对的。


正确的方法是再处理一下逆时针转的结果 最后取较小值。

代码:

#include<iostream>
#include<cstdio>
using namespace std;

int a[10][10];

int min(int a,int b)
{
    return a<b?a:b;
}
int main()
{
   int n;
   while(cin>>n)
   {
      if(n==0)  break;
      for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
          scanf("%d",&a[i][j]);

      int ans=0;
      int steps=0;

      int k=n/2;
      for(int i=0;i<k;i++)    //表示第i层
      {
         int max=-100000000;
         int step1=0,step2=0;
         for(int j=0;j<n-1-2*i;j++)  // j表示第一行第j个  也有差距的含义
          {
             //int cur=a[i+j][i]+a[n-1-i][i+j]+a[n-1-i-j][n-1-i]+a[i][n-1-i-j];
             int cur=a[i][i+j]+a[i+j][n-1-i]+a[n-1-i][n-1-i-j]+a[n-1-i-j][i];
             if(cur>max)
             {
                 step1=n-1-2*i-j;
                 max=cur;
             }
          }
          ans+=max;     //  max怎么旋转来算都行

          max=-100000000;
          for(int j=0;j<n-1-2*i;j++)
          {

             int cur=a[i+j][i]+a[n-1-i][i+j]+a[n-1-i-j][n-1-i]+a[i][n-1-i-j];
             if(cur>max)
             {
                 max=cur;
                 step2=j;
             }
          }

             step1=min(step1,n-1-2*i-step1);
             step2=min(step2,n-1-2*i-step2);

             steps+=min(step1,step2);

      }

      ans+=a[k][k];

      cout<<ans<<' '<<steps<<endl;
   }
}

这个暴力水题还是有点玄机的。

瑕疵是我一开始只做了逆时针旋转,总是wa找出来的

本题的另一个关键点是找出第i层的4个顶点的坐标 (有增量j时) 这个要结合几何性质就很明显了,第一个和第三个,是关于正方形中心中心对称的。



posted @ 2013-09-20 00:13  814jingqi  阅读(123)  评论(0编辑  收藏  举报