zoukankan      html  css  js  c++  java
  • 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时) 这个要结合几何性质就很明显了,第一个和第三个,是关于正方形中心中心对称的。



  • 相关阅读:
    动态规划算法介绍——概念、意义及应用、例题
    两个大数相减
    删除apache的签名的shell脚本
    C++中智能指针的设计和使用
    eclipse save action不起作用
    [leetcode]51. N-QueensN皇后
    [leetcode]33. Search in Rotated Sorted Array旋转过有序数组里找目标值
    [leetcode]88. Merge Sorted Array归并有序数组
    [leetcode]636. Exclusive Time of Functions函数独占时间
    [leetcode]257. Binary Tree Paths二叉树路径
  • 原文地址:https://www.cnblogs.com/814jingqi/p/3339256.html
Copyright © 2011-2022 走看看