• hdu 1998 奇数阶魔方(找规律+模拟)


    应该不算太水吧。

    17  24   1   8  15
      23   5   7  14  16
       4   6  13  20  22
      10  12  19  21   3
      11  18  25   2   9

    对于上面的数据,根据题目中的提示,很容易就看到对角线上的数字是11、12、13、14、15。其他的数据,比如说2,从2往右上查就是2、3、4、5、1。描述起来好像很麻烦,但是对着图看一下就可以很容易看明白。

    接下来继续观察数据,我们可以看出在第一行实际上是从1开始往右查每个数字逐个加上n+2,往左先是n*n-1,然后依次减去n+2。第一行和最后一行根据中心点对称的两个数字的和是n*n+1,比如说17+9=25+1,24+2=25+1。

    有了这两个规律,仅凭直觉,我们都可以确定用来模拟出结果已经足够了。模拟的方法很多,我的方法是将1~n^2分成n段,用第一行的每个数字来确定它所在的斜边的最小值和最大值,比如说对于17,在16、17、18、19、20这个序列中,最小值就是17/5*5+1=16,最大值是(17+5)/5*5=20。有了这两个值,这一个序列的值就很容易确定了。

    1A。

    #include<stdio.h>
    #include<string.h>
    #define N 21
    int map[N][N];
    int main()
    {
        int n;
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            int x=n+1;
            int y=x/2;
            memset(map,0,sizeof(map));
            map[1][y]=1;
            map[n][y]=n*n;
            int temp=n+2;
            int i,j;
            i=y-1;
            j=y+1;
            int tempx,tempy;
            tempx=n*n-1;
            tempy=1+temp;
            while(i>=1&&j<=n)
            {
                map[1][i]=tempx;
                i--;
                tempx-=temp;
                map[1][j]=tempy;
                j++;
                tempy+=temp;
            }
            temp=1+n*n;
            for(i=1; i<=n; i++)
                map[n][i]=temp-map[1][n+1-i];
            int start,end;
            int l,k;
            for(j=1; j<n; j++)
            {
                start=map[1][j]/n*n+1;
                end=(map[1][j]+n)/n*n;
                for(l=2,k=j-1; l<=n&&k>0; l++,k--)
                {
                    if(map[l-1][k+1]!=start)
                        map[l][k]=map[l-1][k+1]-1;
                    else
                        map[l][k]=end;
                }
                for(l=n-1,k=j+2; l>=1&&k<=n; l--,k++)
                {
                    if(map[l+1][k-1]!=end)
                        map[l][k]=map[l+1][k-1]+1;
                    else
                        map[l][k]=start;
                }
    
            }
            for(l=2,k=n-1; l<=n&&k>=1; l++,k--)
            {
                 map[l][k]=map[l-1][k+1]-1;
            }
            for(i=1;i<=n;i++)
            {
                for(j=1;j<=n;j++)
                    printf("%4d",map[i][j]);
                printf("
    ");
            }
        }
        return 0;
    }
    


  • 相关阅读:
    C#如何连接wifi和指定IP
    3.4 小结
    3.3.4.5 起始与清除
    3.3.4.4 打印行
    3.3.4.3 设置字段分隔字符
    3.3.4.2 字段
    3.3.4.1 模式与操作
    3.3.4 使用 awk 重新编排字段
    3.3.3 使用 join 连接字段
    3.3.2 使用 cut 选定字段
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3172381.html
Copyright © 2020-2023  润新知