AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

图形输出问题集锦(更新中)

作者: 作者的头像   无味 ,  2020-08-17 23:31:45 ,  所有人可见 ,  阅读 427


3


1

例题:简单题

1.AcWing 745. 数组的右上半部分

刚开始的思路:

#include<iostream>
using namespace std;
int main()
{
    char c;
    float M[12][12],sum=0;
    cin>>c;
    int cnt=0;
    for(int i=0;i<12;++i)
        for(int j=0;j<12;++j){
            cin>>M[i][j];
            if(j>i){
                sum+=M[i][j];
                cnt++;//求右上半部分有多少个数
            } 
        }
    if(c=='S') printf("%.1f",sum);
    else printf("%.1f",sum/cnt);
    return 0;
}

another:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    char ch;
    double M[12][12];
    double sum=0;
    int cnt=0;
    cin>>ch;
    for(int i=0;i<12;++i)
        for(int j=0;j<12;++j)
            cin>>M[i][j];

    for(int i=0;i<12;++i)
        for(int j=i+1;j<12;++j){
            sum+=M[i][j];
            cnt++;
        }

    if(ch=='S') printf("%.1lf",sum);
    else printf("%.1lf",sum/cnt);

    return 0;
}

第一个思路是找到了右上部分坐标的规律,i>j。但是这个思路不具普遍性。第二个思路是找每行第一个绿色的横坐标与行数的关系。
QQ截图20200817155836.jpg


2.AcWing 747. 数组的左上半部分

刚开始的思路:

#include<iostream>
using namespace std;
int main()
{
    char c;
    double M[12][12],sum=0;
    cin>>c;
    int cnt=0;
    for(int i=0;i<12;++i){
        for(int j=0;j<12;++j){
            cin>>M[i][j];
            if(j<12-i-1){
                sum+=M[i][j];
                cnt++;
            }
        }
    }
    if(c=='S') printf("%.1lf",sum);
    else printf("%.1lf",sum/cnt);
    return 0;
}

anther:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    char ch;
    double M[12][12];
    double sum=0;
    int cnt=0;
    cin>>ch;
    for(int i=0;i<12;++i)
        for(int j=0;j<12;++j)
            cin>>M[i][j];

    for(int i=0;i<12;++i)
        for(int j=0;j<11-i;++j){
            sum+=M[i][j];
            cnt++;
        }

    if(ch=='S') printf("%.1lf",sum);
    else printf("%.1lf",sum/cnt);

    return 0;
}

相比来说,第二个更加简单一点。


3.AcWing 749. 数组的上方区域

刚开始的思路:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    char c;
    float M[12][12],sum=0;
    int cnt=0;
    cin>>c;
    for(int i=0;i<12;i++)
        for(int j=0;j<12;j++){
            cin>>M[i][j];
            if(i<5&&j<12-i-1&&j>i){
                sum+=M[i][j];
                cnt++;
            }
        }

    if(c=='S') printf("%.1f",sum);
    else printf("%.1f",sum/cnt);
    return 0;
}

another:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    char ch;
    double M[12][12];
    double sum=0;
    int cnt=0;
    cin>>ch;
    for(int i=0;i<12;++i)
        for(int j=0;j<12;++j)
            cin>>M[i][j];

    for(int i=0;i<5;++i)
        for(int j=i+1;j<11-i;++j){
            sum+=M[i][j];
            cnt++;
        }

    if(ch=='S') printf("%.1lf",sum);
    else printf("%.1lf",sum/cnt);

    return 0;
}

相比来说还是思路二简单,而且不易出错。


4.AcWing 751. 数组的左方区域

刚开始的思路:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    char c;
    float M[12][12],sum=0;
    int cnt=0;
    cin>>c;
    for(int i=0;i<12;i++)
        for(int j=0;j<12;j++){
            cin>>M[i][j];
            if(i>0&&i<=5&&j<=i){
                sum+=M[i][j];
                cnt++;
            } 
            if(i>5&&i<11&&j<12-i){
                sum+=M[i][j];
                cnt++;
            }
        }
    if(c=='S') printf("%.1f",sum);
    else printf("%.1f",sum/cnt);
    return 0;
}

another:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    char ch;
    double M[12][12];
    double sum=0;
    int cnt=0;
    cin>>ch;
    for(int i=0;i<12;++i)
        for(int j=0;j<12;++j)
            cin>>M[i][j];

    for(int i=1;i<=5;++i)
        for(int j=0;j<i;++j){
            sum+=M[i][j];
            cnt++;
        }
    for(int i=6;i<=10;++i)
        for(int j=0;j<11-i;++j){
            sum+=M[i][j];
            cnt++;
        }                       //这次和前面不一样,分成了两步。


    if(ch=='S') printf("%.1lf",sum);
    else printf("%.1lf",sum/cnt);

    return 0;
}

5. AcWing 748. 数组的右下半部分

刚开始的思路:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    double M[12][12];
    char ch;
    cin>>ch;
    for(int i=0;i<12;++i)
        for(int j=0;j<12;++j)
            cin>>M[i][j];

    double sum=0,cnt=0;
    for(int i=1;i<=11;++i)
        for(int j=12-i;j<=11;++j){
            cnt++;
            sum+=M[i][j];
        }

    if(ch=='S') printf("%.1lf",sum);
    else printf("%.1lf",sum/cnt);
    return 0;
}

6. AcWing 746. 数组的左下半部分

刚开始的思路:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    double M[12][12];
    char ch;
    cin>>ch;
    for(int i=0;i<12;++i)
        for(int j=0;j<12;++j)
            cin>>M[i][j];

    double sum=0,cnt=0;
    for(int i=1;i<=11;++i)
        for(int j=0;j<i;++j){
            cnt++;
            sum+=M[i][j];
        }

    if(ch=='S') printf("%.1lf",sum);
    else printf("%.1lf",sum/cnt);
    return 0;
}

7. AcWing 750. 数组的下方区域

刚开始的思路:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    double M[12][12];
    char ch;
    cin>>ch;
    for(int i=0;i<12;++i)
        for(int j=0;j<12;++j)
            cin>>M[i][j];

    double sum=0,cnt=0;
    for(int i=7;i<12;++i)
        for(int j=12-i;j<=i-1;++j){
            cnt++;
            sum+=M[i][j];
        }

    if(ch=='S') printf("%.1lf",sum);
    else printf("%.1lf",sum/cnt);
    return 0;
}

8. AcWing 752. 数组的右方区域

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    double M[12][12];
    char ch;
    cin>>ch;
    for(int i=0;i<12;i++)
        for(int j=0;j<12;++j)
            cin>>M[i][j];

    double sum=0,cnt=0;
    for(int i=1;i<=5;++i)
        for(int j=12-i;j<=11;j++){
            cnt++;
            sum+=M[i][j];
        }
    for(int i=6;i<=10;i++)
        for(int j=i+1;j<=11;++j){
            cnt++;
            sum+=M[i][j];
        }

    if(ch=='S') printf("%.1lf",sum);
    else printf("%.1lf",sum/cnt);
    return 0;
}



例题:困难题

1. AcWing 753. 平方矩阵 I

QQ截图20200817163505.jpg

#include<iostream>
using namespace std;
int main()
{
    int n,upon,under,left,right;
    int N[110][110];
    while(cin>>n,n>0){
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j){
                upon=i;
                under=n-i+1;
                left=j;
                right=n-j+1;
                N[i][j]=min(min(upon,under),min(left,right));
            }
        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j)
            cout<<N[i][j]<<" ";
        cout<<endl;
        }

        cout<<endl;
    }
    return 0;
}
#include<iostream>
using namespace std;
int main()
{
    int n;
    while(cin>>n,n){
        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j){
                int up=i,down=n-i+1,left=j,right=n-j+1;
                cout<<min(min(up,down),min(left,right))<<" ";
            }
        cout<<endl;
        }

        cout<<endl;
    }
    return 0;
}

此题其实不用开数组。
注意双重for循环的i和j要从1开始!!!


2. AcWing 754. 平方矩阵 II

这个题的规律不难发现:(1)对角线数值为1;(2)数值关于对角线对称;(3)每行从对角线数值开始逐个+1;
这样的话,我们就可以先将对角线上的数值初始为1,然后计算出对角线上方的部分(从对角线开始逐个+1),最后求对角线下方的部分(a[j][i]=a[i][j])

#include<iostream>
using namespace std;
int main()
{
    int n;
    int N[110][110];
    while(cin>>n,n){
        for(int i=1;i<=n;++i){
            N[i][i]=1;
            for(int j=i+1;j<=n;j++){
                N[i][j]=N[i][j-1]+1;
                N[j][i]=N[i][j];
            }
        }

        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j)
                cout<<N[i][j]<<" ";

            cout<<endl;
        }  

        cout<<endl;
    }
    return 0;
}

another:

#include<iostream>

using namespace std;

int q[100][100];

int main()
{
    int n;
    while(cin >> n, n){
        for(int i=0; i<n; ++i)
        {
            q[i][i] = 1;
            for(int j = i + 1, k = 2;j < n; ++j, ++k) q[i][j] = k;
            for(int j = i + 1, k = 2;j < n; ++j, ++l) q[j][i] = k;
        }

        for(int i = 0; i < n; ++i )
        {
            for(int i = 0;i < n; ++i) cout << q[i][j] << " ";
            cout << endl;
        }
        cout << endl;
    }
    return 0;
}

3. AcWing 756. 蛇形矩阵

刚开始没有思路,看了y总视频看了一半写出来的:

#include<iostream>
using namespace std;

int a[100][100];
bool b[100][100];
int main()
{
    int n,m;
    int dx[]={0,1,0,-1},dy[]={1,0,-1,0};//下标一定要从1开始!!!!
    cin>>n>>m;
    int x=0,y=0,cnt=0;
    for(int i=1;i<=n*m;++i){
        a[x][y]=i;
        b[x][y]=true;//填入数值的显示为true;

        if((x+dx[cnt%4]==0)&&(y+dy[cnt%4]==m)||(x+dx[cnt%4]==n)&&(y+dy[cnt%4]==m-1)||(x+dx[cnt%4]==n-1)&&(y+dy[cnt%4]==-1)||b[x+dx[cnt%4]][y+dy[cnt%4]]==true)
            cnt++;      //这个cnt%4是个值得思考的地方,有点东西!!!!!

        x=x+dx[cnt%4];
        y=y+dy[cnt%4];//此操作是让下一个值接收i。
    }

    for(int i=0;i<n;++i){
        for(int j=0;j<m;++j)
            cout<<a[i][j]<<" ";
    cout<<endl;
    }
    return 0;
}

感觉这个地方中cnt%4写的很有水平,嘿嘿嘿。忘记是在哪看到别人用到过,意识中就用上了.

下面说一下y总的完整思路:
QQ截图20200817233110.jpg

#include<iostream>
using namespace std;

int res[100][100];//全局变量的初始值为零!!!

int main()
{
    int n, m;
    cin >> n >> m;

    int dx[] = {0, 1, 0, -1}, dy[] =  {1, 0, -1, 0};//下标一定要从1开始!!!!

    for (int x = 0, y = 0, d = 0, k = 1; k <= n * m; ++k)//此处一些变量我都是在for之前定义的,y总都定义在括号内,这样看起来更简洁易懂。
    {
        res[x][y] = k;
        int a = x + dx[d], b = y + dy[d];
        if(a < 0 || a >= n || b < 0 || b >= m || res[a][b])//此处的res[a][b]和全局变量res[100][100]遥相呼应,因为全局变量的初始值为零,而局部变量的初始值不确定,所以此处未执行的变量为零,执行过的变量不为0;
        {//上面的判断条件比我的更简洁,是我想复杂了.
            d = (d + 1) % 4;    //此处和我的原理其实一样,我的是先++,再放到数组中。
            a = x + dx[d], b = y + dy[d];
        }
        x = a, y = b;
    }

    for(int i = 0; i < n; ++i)//注意此处是从零开始的!!!
    {
        for(int j = 0; j < m; j ++) cout << res[i][j] << " ";
        cout << endl;
    }
    return 0;
}

QQ截图20200817225655.jpg

后来又做这道题的时候,dx[]和dy[]数组是从下标1开始的,所以就一直运行出错,后来发现问题就出在这,应该从0开始,以后要注意,碰到要取模循环的时候下标一定要从0开始!!!!!


4.AcWing 螺旋折线 第九届蓝桥杯省赛C++B组

这个题第一眼做的时候脑中就觉着有些熟悉,一想不就是上边那道题吗,于是就按照上边的思路做,模拟,但是具体一想跟上边还不一样,蛇形矩阵那道题是从外到内,这个题是从内到外,这个要转向的条件不好想,想了好一会.
QQ截图20201012201044.jpg

#include<iostream>
using namespace std;
int dx[]={-1,0,1,0},dy[]={0,1,0,-1},dz[]={1,0,1,0};
int x,y;
int main()
{
        int m=0,n=0;//表示每一次点的坐标
        long long num=1;//表示sum达到这个数值就要转向
        long long sum=0;//坐标每变化一次,sum++,当sum等于num的时候,表示要转向了 
        long long l=0;//l表示左 上 右 下 左 上 右 下...取模变化的值
        long long k=0;//k表示1 1 2 2 3 3 4 4 5 5...取模变化的值
        long long cnt=0;//表示dis(x,y)
        while(true)
        {
            if(m==x&&n==y) break;

            m=m+dx[l%4];
            n=n+dy[l%4];
            //cout<<m<<" "<<n<<endl;
            cnt++;
            sum++;

            if(sum==num){
                l++;
                k++;

                num=num+dz[k%4];
                sum=0;
            }
        }

        cout<<cnt<<endl;

    return 0;
}

写出来后回过头再来看这个题的切入点就是那个转向条件,什么时候转向,转向后哪些变量发生变化,这些搞明白后其他的就很简单了

调试了几个图上的点后满心欢喜的提交,却显示TLE,唉,一看没通过的样例,(498103014,945809204),这才发现这个题因为范围的原因不能用上面模拟这个思路.(吃饭的时候把TLE这个样例在Dev上跑了一下,跑了半个小时,x和y的值才刚刚过百…)

这个题既然不能用模拟来解决,那么就是有公式或者有规律了,观察了一下,还真发现了规律:(有图的题都要去画一下)

QQ截图20201012205026.jpg

#include<iostream>
using namespace std;
int dx[]={-1,0,1,0},dy[]={0,1,0,-1},dz[]={1,0,1,0};
int x,y;
int main()
{
    cin>>x>>y;
    int m=0,n=0;//表示每一次点的坐标
    long long num=1;//表示sum达到这个数值就要转向
    long long sum=0;//坐标每变化一次,sum++,当sum等于num的时候,表示要转向了 
    long long l=0;//l表示dx,dy的值
    long long k=0;//k表示1 1 2 2 3 3 4 4 5 5...取模变化的值
    long long cnt=0;//表示dis(x,y)

    if(abs(x)*abs(y)>6)
    {
        if(x==0)
        {
            if(y>0)
            {
                cnt=(y-2)*19+(y-2)*(y-3)*8/2;
                x=0;y=2;
                while(true)
                {
                    if(m==x&&n==y) break;

                    m=m+dx[l%4];
                    n=n+dy[l%4];
                    //cout<<m<<" "<<n<<endl;
                    cnt++;
                    sum++;

                    if(sum==num){
                        l++;
                        k++;

                        num=num+dz[k%4];
                        sum=0;
                    }
                }
            }
            else
            {
                cnt=(abs(y)-2)*23+(abs(y)-2)*(abs(y)-3)*8/2;
                x=0;y=-2;
                while(true)
                {
                    if(m==x&&n==y) break;

                    m=m+dx[l%4];
                    n=n+dy[l%4];
                    //cout<<m<<" "<<n<<endl;
                    cnt++;
                    sum++;

                    if(sum==num){
                        l++;
                        k++;

                        num=num+dz[k%4];
                        sum=0;
                    }
                }
            }
        }
        else if(y==0)
        {
            if(x>0)
            {
                cnt=(x-2)*21+(x-2)*(x-3)*8/2;
                x=2;y=0;
                while(true)
                {
                    if(m==x&&n==y) break;

                    m=m+dx[l%4];
                    n=n+dy[l%4];
                    //cout<<m<<" "<<n<<endl;
                    cnt++;
                    sum++;

                    if(sum==num){
                        l++;
                        k++;

                        num=num+dz[k%4];
                        sum=0;
                    }
                }
            }
            else
            {
                cnt=(abs(x)-2)*17+(abs(x)-2)*(abs(x)-3)*8/2;
                x=-2;y=0;
                while(true)
                {
                    if(m==x&&n==y) break;

                    m=m+dx[l%4];
                    n=n+dy[l%4];
                    //cout<<m<<" "<<n<<endl;
                    cnt++;
                    sum++;

                    if(sum==num){
                        l++;
                        k++;

                        num=num+dz[k%4];
                        sum=0;
                    }
                }
            }
        }
        else
        {
            if(x>0&&y>0)//第一象限
            {
                if(x>=y)//对角线之下
                {
                    cnt=(x-2)*20+(x-2)*(x-3)*8/2;
                    y=y-(x-2);x=2;
                }
                else//对角线之上
                {
                    cnt=(y-2)*20+(y-2)*(y-3)*8/2;
                    x=x-(y-2);y=2;
                }

            }
            else if(x<0&&y>0)//第二象限
            {
                if(abs(x)>=abs(y))//对角线之下
                {
                    cnt=(abs(x)-2)*18+(abs(x)-2)*(abs(x)-3)*8/2;
                    y=y-(abs(x)-2);x=-2;
                }
                else//对角线之上
                {
                    cnt=(abs(y)-2)*18+(abs(y)-2)*(abs(y)-3)*8/2;
                    x=x+(y-2);y=2;
                }
            }
            else if(x>0&&y<0)//第三象限
            {
                if(abs(x)>=abs(y))//对角线之上
                {
                    cnt=(x-2)*22+(x-2)*(x-3)*8/2;
                    y=y+(x-2);x=2;
                }
                else//对角线之下
                {
                    cnt=(abs(y)-2)*22+(abs(y)-2)*(abs(y)-3)*8/2;
                    x=x-(abs(y)-2);y=-2;
                }
            }
            else{//第四象限
                if(x>=y)//对角线之下
                {
                    cnt=(abs(y)-2)*24+(abs(y)-2)*(abs(y)-3)*8/2;
                    x=x+(abs(y)-2);y=-2;
                }
                else//对角线之上
                {
                    cnt=(abs(x)-3)*24+(abs(x)-3)*(abs(x)-4)*8/2;
                    y=y+(abs(x)-3);x=-3;
                }
            }
            while(true)
            {
                if(m==x&&n==y) break;

                m=m+dx[l%4];
                n=n+dy[l%4];
                //cout<<m<<" "<<n<<endl;
                cnt++;
                sum++;

                if(sum==num){
                    l++;
                    k++;

                    num=num+dz[k%4];
                    sum=0;
                }
            }
        }
    }
    else
    {
            while(true)
            {
                if(m==x&&n==y) break;

                m=m+dx[l%4];
                n=n+dy[l%4];
                //cout<<m<<" "<<n<<endl;
                cnt++;
                sum++;

                if(sum==num){
                    l++;
                    k++;

                    num=num+dz[k%4];
                    sum=0;
                }
            }
    }

    cout<<cnt;
    return 0;
}
//说实话上边这个代码写了一天...

四个象限运行样例都正确后提交还是显示超时,为什么会超时呢,按照上面的思路,以341238 572290为例,因为在对角线上方,首先要定位到横坐标为2,那么这个坐标就是(-231050,2),当时看到这个结果有点惊讶,想了一下明白了,之前试的样例都是太小了,这个x和y相差太大了,所以就去了别的象限,所以上边的思路还是有bug的,但是现在不用改上面的bug了,因为改完后就会定位到(231050,2)这个位置输入到while循环之中后还是会TLE.所以这个思路对x和y很大并且x和y的差值较大时不合适.
还有输入108 -2时输出的答案也不对,它是定位到了(2,104),和自己想的有出入。这也说明其实上边的思路有很大的问题.

冥冥之中感觉这个题肯定是围绕等差数列这个规律来计算的,只不过有些小细节上不对,既然定位到蓝线上后再运行还是会存在x或者y有可能很大的情况,那么这个先定位到蓝线上就不可取了.
通过观察,完全可以定位到0:
222.jpg

#include<iostream>
#include<math.h>
using namespace std;
int main()
{
    long long x,y;
    long long cnt=0,num;
    cin>>x>>y;
    if(x==0)
    {
        if(y>0)
            cnt=y*3+y*(y-1)*8/2;
        else
            cnt=abs(y)*7+abs(y)*(abs(y)-1)*8/2;
    }
    else if(y==0)
    {
        if(x>0)
           cnt=x*5+x*(x-1)*8/2; 
        else
            cnt=abs(x)+abs(x)*(abs(x)-1)*8/2;
    }
    else
    {
        if(x>0&&y>0)//第一象限
        {
            if(x>y)//对角线下
            {    
                num=x-y;//+
                cnt=x*4+x*(x-1)*8/2+num;
            }
            else
            {
                num=x-y;//-
                cnt=y*4+y*(y-1)*8/2+num;
            }
        }
        else if(x<0&&y>0)//第二象限
        {
            if(abs(x)>y)//对角线下
            {    
                num=x+y;//-
                cnt=abs(x)*2+abs(x)*(abs(x)-1)*8/2+num;
            }
            else
            {
                num=x+y;//+
                cnt=y*2+y*(y-1)*8/2+num;
            }
        }
        else if(x>0&&y<0)//第四象限
        {
            if(x>=abs(y))//对角线上
            {    
                num=abs(y)-x;//-
                cnt=x*6+x*(x-1)*8/2+num;
            }
            else
            {
                num=abs(y)-x;//+
                cnt=abs(y)*6+abs(y)*(abs(y)-1)*8/2+num;
            }
        }
        else//第三象限
        {
            if(x<y)//线上
            {
                num=y-x-1;//+
                cnt=(abs(x)-1)*8+(abs(x)-1)*(abs(x)-2)*8/2+num+1;
            }
            else
            {
                num=y-x-1;//-
                //cout<<num<<endl;
                cnt=abs(y)*8+abs(y)*(abs(y)-1)*8/2+num+1;
            }
        }
    }
    cout<<cnt<<endl;

    return 0;
}

y总说这个模拟可以按照每一步来模拟,当然也可以按照每一行或者一列来模拟:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;
 typedef long long LL;

 int main()
 {
    int x,y;
    cin >> x >> y;

    int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};

    int a = 0,b = 0, dir = 3,step = 0;
    LL distance = 0;

    while(true)
    {
        int l = step / 2 + 1;
        int c = a + dx[dir] * l,d = b + dy[dir]*l;

        if(a ==c && a==x &&min(b,d) <=y && man(b,d) >=y)
        {
            cout << distance + abs(y - b) << endl;
            break;
        }
        if(b ==d && b == y && min(a,c) <= x && max(a,c) >=x)
        {
            cout << distance + abs(x - a) << endl;
            break;
        } 
        distance += l;
    dir = (dir + 1) % 4,step ++;
    a = c,b = d;
    }   
    return 0;
 }

下面来看一下y总的规律做法:
QQ截图20201013093036.jpg
QQ截图20201013092410.jpg

#include<iostream>
#include<math.h>
using namespace std;
int main()
{
    long long x,y;
    long long cnt=0,num;
    cin>>x>>y;
    if(abs(x)<=y)//上
    {
        num=y-x;
        cnt=2*y*2*y-num;
    }
    else if(abs(y)<=x)//右边
    {
        num=abs(0-x-y);
        cnt=2*x*(2*x+1)-num;
    }
    else if(abs(x)<abs(y)+1)//下边
    {
        num=abs(y)-x;
        cnt=(2*abs(y))*(2*abs(y)+1)+num;
    }
    else//左边
    {
        num=abs(x)-y;
        cnt=(2*abs(x)-1)*2*abs(x)-num;
    }
    cout<<cnt<<endl;

    return 0;
}

上边是听了y总的思路自己写的代码
下面是y总的代码:

#include<iostream>
using namespace std;

typedef long long LL;

int main()
{
    int x,y;
    cin>>x>>y;

    if(abs(x)<=y)//在上方
    {
        int n=y;
        cout<<(LL)(2*n-1)*(2*n)+x-(-n)<<endl;
    }
    else if(abs(y)<=x)//在右方
    {
        int n=x;
        cout<<(LL)(2*n)*(2*n)+n-y<<endl;
    }
    else if(abs(x)<=abs(y)+1 && y<0)//在下方
    {
        int n=abs(y);
        cout<<(LL)(2*n)*(2*n+1)+n-x<<endl;
    }
    else//在左方
    {
        int n=abs(x);
        cout<<(LL)(2*n-1)*(2*n-1)+y-(-n+1)<<endl;
    }

    return 0;
}
//y总上边到左上顶点,右边到右上顶点,下边到右下顶点,左边到左下顶点

总结:
QQ截图20201013104747.jpg

0 评论

App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息