zoukankan      html  css  js  c++  java
  • EOJ3536 求蛇形矩阵每一行的和---找规律

    题目链接:

    https://acm.ecnu.edu.cn/problem/3536/

    题目大意:

    求蛇形矩阵的每一行的和,数据范围n<=200000。

    思路:

    由于n数据较大,所以感觉应该是需要找规律。

    先附上蛇形矩阵的打表代码,先输出数据较小的蛇形矩阵,观察规律。

     1 #include <iostream>
     2 #include <malloc.h>
     3 using namespace std;
     4 int arr[100][100];
     5 int startNum=1;
     6 void DrawCircle(int len,int n);
     7 int main(){
     8     int i,j,k,n,len;
     9     cout<<"请输入蛇形矩阵阶数n
    n=";
    10     cin>>n;
    11     len=n;
    12     if(n%2!=0){
    13         while(len>1){
    14             DrawCircle(len,n);
    15             len=len-2;
    16         }
    17         arr[n/2+1][n/2+1]=n*n;
    18     }
    19     else{
    20         while(len>1){
    21             DrawCircle(len,n);
    22             len=len-2;
    23         }
    24     }
    25     cout<<"对应的蛇形矩阵如下"<<endl;
    26     for(i=1;i<=n;i++){
    27         for(j=1;j<=n;j++){
    28             cout<<arr[i][j];
    29             if(j<n){
    30                 if(arr[i][j]>=10)
    31                     cout<<" ";
    32                 else
    33                     cout<<"  ";
    34             }
    35             else
    36                 cout<<endl;
    37         }
    38     }
    39     for(int i = 1; i <= n; i++)
    40     {
    41         int tot = 0;
    42         for(int j = 1; j <= n; j++)tot += arr[i][j];
    43         cout<<tot<<endl;
    44     }
    45     return 0;
    46 }
    47 void DrawCircle(int len,int n){
    48     int i,number,row,col;
    49     number=(n-len)/2+1;//当前画的是第几个圈
    50     row=number;col=number;
    51     for(i=1;i<=len;i++){
    52         arr[row][col]=startNum++;
    53         col++;
    54     }
    55     col--;//for循环要跳出时候,列数多加了一次,这个地方减掉
    56     for(i=1;i<=len-1;i++){
    57         row++;
    58         arr[row][col]=startNum++;
    59     }
    60     for(i=1;i<=len-1;i++){
    61         col--;
    62         arr[row][col]=startNum++;
    63     }
    64     for(i=1;i<=len-2;i++){
    65         row--;
    66         arr[row][col]=startNum++;
    67     }
    68 }

    举个例子,先观察n = 9的时候。

    对应的蛇形矩阵如下

    1  2  3  4  5  6  7  8  9
    32 33 34 35 36 37 38 39 10
    31 56 57 58 59 60 61 40 11
    30 55 72 73 74 75 62 41 12
    29 54 71 80 81 76 63 42 13
    28 53 70 79 78 77 64 43 14
    27 52 69 68 67 66 65 44 15
    26 51 50 49 48 47 46 45 16
    25 24 23 22 21 20 19 18 17


    第一行的和是S1 = 9*10/2=45。

    第二行前8位比第一行多31,第9位多1,S2 = 31*8+1+S1=294

    第三行第2位到第7位比第二行多23, 第1位少1,后1位多1正好抵消,第8位多1,所以S3 = 23*6+1+S2=433

    第四行第3位到第6位比第三行多15, 前2位少1,后2位多1正好抵消,第7位多1,所以S4 = 15*4+1+S3=494

    第五行第4位到第5位比第三行多7, 前3位少1,后3位多1正好抵消,第6位多1,所以S5 = 7*2+1+S4=509

     这是上面的前半部分的规律,从a = 4 * n - 5(4*9-5=31), b = n - 1(9-1=8)开始,a依次减8,b依次减2

    第六行比第五行前4位少1, 后4位多1,中间1位少3,S6 = S5-1*3=506

    第七行比第六行前3位少1, 后3位多1,中间3位少11, S7 = S6 - 3*11=473

    第八行比第七行前2位少1, 后2位多1,中间5位少19, S8 = S7 - 5*19=378

    第九行比第八行前1位少1, 后1位多1,中间7位少27, S9 = S8 - 7*27=189

    后半部分的规律是从a = 3, b = 1开始,a依次加8, b依次加2

    以上是n为奇数的规律,偶数的规律也类似:
    以n = 6为例:

    对应的蛇形矩阵如下
    1   2   3   4   5   6
    20 21 22 23 24 7
    19 32 33 34 25 8
    18 31 36 35 26 9
    17 30 29 28 27 10
    16 15 14 13 12 11

    前三行的规律和上面一样,

    S1 = 6 * 7 / 2 = 21

    S2 = 19 * 5 + 1 + S1=117

    S3 = 11 * 3 + 1 + S2=151

    后三行的规律是

    S4 = S3 + 4

    S5 = S4 - 2 * 7

    S6 = S5 - 4 * 15

    多找几组偶数会发现每次都是这样的规律,后半部分的第一行 = 前半部分的最后一行 + 4,然后的规律都是依次减去a*b,a最开始为2,b最开始为7,之后依次a+=2,b+=8.

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<string>
     6 #include<cmath>
     7 #include<set>
     8 #include<queue>
     9 #include<map>
    10 #include<stack>
    11 #include<vector>
    12 #include<list>
    13 #include<deque>
    14 #include<sstream>
    15 #include<cctype>
    16 #define REP(i, n) for(int i = 0; i < (n); i++)
    17 #define FOR(i, s, t) for(int i = (s); i < (t); i++)
    18 #define MEM(a, x) memset(a, x, sizeof(a));
    19 #define DEBUG(x) cout<<x<<endl;
    20 #define DBG cout<<"----------------"<<endl;
    21 #define mid(x, y) x + (y - x)/ 2
    22 #define lc o<<1
    23 #define rc o<<1|1
    24 using namespace std;
    25 typedef long long ll;
    26 typedef unsigned long long ull;
    27 typedef pair<int, int> Pair;
    28 const int maxn = 1e6 + 10;
    29 const double eps = 1e-10;
    30 const int INF = 1e9;
    31 const int dir[4][2] = {1,0,0,1,0,-1,-1,0};
    32 const double pi = 3.1415926535898;
    33 ll T, n, m, cases;
    34 int main()
    35 {
    36     std::ios::sync_with_stdio(false);
    37     cin >> n;
    38     if(n & 1)//奇数的时候
    39     {
    40         ll a1 = (n + 1) * n / 2;//求出第一行
    41         cout<<a1<<endl;
    42         ll a = 4 * n - 5, b = n - 1;//a,b初始值
    43         int i;
    44         for(i = 2; i <= (n + 1) / 2; i++)//前半部分输出
    45         {
    46             a1 = a1 + 1 + a * b;
    47             a -= 8;
    48             b -= 2;
    49             cout<<a1<<endl;
    50         }
    51         a = 3, b = 1;
    52         for(;i <= n; i++)//后半部分输出
    53         {
    54             a1 = a1 - a * b;
    55             cout<<a1<<endl;
    56             a += 8;
    57             b += 2;
    58         }
    59     }
    60     else//n为偶数
    61     {
    62         ll a1 = (n + 1) * n / 2;//输出第一个
    63         cout<<a1<<endl;
    64         ll a = 4 * n - 5, b = n - 1;
    65         int i;
    66         for(i = 2; i <= (n + 1) / 2; i++)//前半部分和之前一样的规律
    67         {
    68             a1 = a1 + 1 + a * b;
    69             a -= 8;
    70             b -= 2;
    71             cout<<a1<<endl;
    72         }
    73         a1 += 4;
    74         cout<<a1<<endl;//中间的特殊规律
    75         a = 2, b = 7;
    76         i++;//这里i++保证输出正好n行
    77         for(;i <= n; i++)//后半部分输出
    78         {
    79             a1 = a1 - a * b;
    80             a += 2;
    81             b += 8;
    82             cout<<a1<<endl;
    83         }
    84     }
    85     return 0;
    86 }

    注意坑点:最好所有的变量设成long long,如果n是int的话,计算a1 = (n + 1) * n / 2;的时候会溢出,导致出错。

  • 相关阅读:
    Java-JUC(十二):有3个线程。线程A和线程B并行执行,线程C需要A和B执行完成后才能执行。可以怎么实现?
    Spark2.x(五十九):yarn-cluster模式提交Spark任务,如何关闭client进程?
    Spark2.x(五十七):User capacity has reached its maximum limit(用户容量已达到最大限制)
    Spark2.x(五十六):Queue's AM resource limit exceeded.
    Java-Maven(十二):idea多项目:common module进行compiler和install正常,运行domain-perf module提示:Could not resolve dependencies for project
    Linux Shell:Map的用法
    Spark2.x(五十五):在spark structured streaming下sink file(parquet,csv等),正常运行一段时间后:清理掉checkpoint,重新启动app,无法sink记录(file)到hdfs。
    Linux Shell:根据指定的文件列表 或 map配置,进行文件位置转移
    Java-Maven(十一):Maven 项目出现pom.xml错误:Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-compiler-plugin
    Spark2.x(五十四):在spark structured streaming下测试ds.selectExpr(),当返回列多时出现卡死问题。
  • 原文地址:https://www.cnblogs.com/fzl194/p/8679019.html
Copyright © 2011-2022 走看看