首页 > 其他分享 >[Luogu] P1058 [NOIP2008 普及组] 立体图

[Luogu] P1058 [NOIP2008 普及组] 立体图

时间:2023-12-24 21:22:39浏览次数:49  
标签:int Luogu 立体图 NOIP2008 -- 坐标 左上角 长方体

P1058 [NOIP2008 普及组] 立体图

模拟赛时候要是做出来这题就能拿饮料了:(

题目传送门

思路

先打个输出长方体的函数:(其中\((x,y)\)表示该长方体的左上角)

void draw(int x,int y)
{
    c[x][y+2]='+';c[x][y+6]='+';c[x+2][y]='+';c[x+2][y+4]='+';
    c[x+5][y]='+';c[x+5][y+3]='+';c[x+5][y+4]='+';c[x+3][y+6]='+';

    c[x][y+3]='-';c[x][y+4]='-';c[x][y+5]='-';
    c[x+2][y+1]='-';c[x+2][y+2]='-';c[x+2][y+3]='-';
    c[x+5][y+1]='-';c[x+5][y+2]='-';c[x+5][y+3]='-';

    c[x+1][y+1]='/';c[x+1][y+5]='/';c[x+4][y+5]='/';

    c[x+1][y+6]='|';c[x+2][y+6]='|';c[x+3][y]='|';
    c[x+4][y]='|';c[x+3][y+4]='|';c[x+4][y+4]='|';

    c[x+2][y+5]=' ';c[x+3][y+1]=' ';c[x+3][y+2]=' ';c[x+3][y+3]=' ';
    c[x+3][y+5]=' ';c[x+4][y+1]=' ';c[x+4][y+2]=' ';c[x+4][y+3]=' ';
    c[x+1][y+2]=' ';c[x+1][y+3]=' ';c[x+1][y+4]=' ';
}

接着,就是去找到每一个长方体的左上角的坐标,找规律即可得到:(这里将左下角的格子看作是\(1,1\))

x=(i-1)*2+4+3*(k-1)+1;
y=2*(n-i)+4*(j-1)+1;

那么整个图形的长宽就是每个\(x,y\)的最大值加上对应补上的值(因为我们这是算的左上角坐标,并不是完整坐标

其中的\(k\)表示当前处于第\(k\)层,我是用了一个三维数组存:

\(a_{i,j,k}\)表示坐标为\((i,j)\)处,第\(k\)层的数的左上角坐标

最后,先枚举每一层(即\(k\)),再从后往前画,也就是倒着枚举\(i,j\),每次画一下对应的长方体即可

还有一点需要注意,因为我们假设的\((1,1)\)是左下角(这样推式子方便),与题目不符,所以每次画的时候都需要将其转化为题目所要求的(具体可见代码)

这里的输入也要倒序输入,因为我的式子也是基于他倒序的情况之下的

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,dn,dm,maxn;
char c[1010][1010];
struct pos
{
    int x,y,data;
}a[60][60][110];
void draw(int ,int y);
void print()
{
    for(int i=1;i<=dn+1;i++)
    {
        for(int j=1;j<=dm+6;j++)
        {
            cout<<c[i][j];
        }
        cout<<endl;
    }
    cout<<endl;
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    for(int i=1;i<=1000;i++)
        for(int j=1;j<=1000;j++)
            c[i][j]='.';
    cin>>n>>m;
    for(int i=n;i>=1;i--)
    {
        for(int j=m;j>=1;j--)
        {
            cin>>a[i][j][0].data;
            for(int k=1;k<=a[i][j][0].data;k++)
            {
                a[i][j][k].x=(i-1)*2+4+3*(k-1)+1;
                a[i][j][k].y=2*(n-i)+4*(j-1)+1;
                dn=max(dn,a[i][j][k].x);
                dm=max(dm,a[i][j][k].y);
            }
            maxn=max(maxn,a[i][j][0].data);
        }
    }
    for(int k=1;k<=maxn;k++)
    {
        for(int i=n;i>=1;i--)
        {
            for(int j=m;j>=1;j--)
            {
                if(a[i][j][0].data<k) continue;
                draw(dn+1-a[i][j][k].x,dm+1-a[i][j][k].y);
                //这里就是将坐标转为题目所述的
            }
        }
    }
    print();
    system("echo. & pause");
    return 0;
}
void draw(int x,int y)
{
    c[x][y+2]='+';c[x][y+6]='+';c[x+2][y]='+';c[x+2][y+4]='+';
    c[x+5][y]='+';c[x+5][y+3]='+';c[x+5][y+4]='+';c[x+3][y+6]='+';

    c[x][y+3]='-';c[x][y+4]='-';c[x][y+5]='-';
    c[x+2][y+1]='-';c[x+2][y+2]='-';c[x+2][y+3]='-';
    c[x+5][y+1]='-';c[x+5][y+2]='-';c[x+5][y+3]='-';

    c[x+1][y+1]='/';c[x+1][y+5]='/';c[x+4][y+5]='/';

    c[x+1][y+6]='|';c[x+2][y+6]='|';c[x+3][y]='|';
    c[x+4][y]='|';c[x+3][y+4]='|';c[x+4][y+4]='|';

    c[x+2][y+5]=' ';c[x+3][y+1]=' ';c[x+3][y+2]=' ';c[x+3][y+3]=' ';
    c[x+3][y+5]=' ';c[x+4][y+1]=' ';c[x+4][y+2]=' ';c[x+4][y+3]=' ';
    c[x+1][y+2]=' ';c[x+1][y+3]=' ';c[x+1][y+4]=' ';
}

标签:int,Luogu,立体图,NOIP2008,--,坐标,左上角,长方体
From: https://www.cnblogs.com/lyk2010/p/17924872.html

相关文章

  • luogu1972题解
    还是先写被卡的做法吧。节点的区间用了现用现计算卡常过了。被卡了一上午,难过。话说有人说我码风有点抽象。思路主席树做法。a[i]是贝壳序列。先求出nxt,即与a[i]相同的下一个a[j]的下标j。用p114514[i]记了值为\(i\)的数的下标,循环到序列第\(j\)个数的时候,先......
  • luogu P9753题解
    题意描述有一个字符串,请你求出有多少个字串可以经过若干次,使它变成空串其中每次操作可以从字符串中删除两个相邻的相同字符,操作后剩余字符串会拼接在一起。##思路1可以枚举左端点,再枚举右端点,一边枚举一边判断是否合法时间复杂度$O(n^2)$空间复杂度$O(n)$##思......
  • Luogu-P4654-[CEOI2017] Mousetrap
    前言模拟赛之后被胁迫上去讲这题,没怎么准备,然后就在几个省的OIer面前当小丑。。倒是把我自己讲得很明白,但感觉对其他人不是很负责任,就来赎罪一下。。更好的阅读体验。题意题目链接。分析以\(t\)为根,我们的目的是让老鼠走到根的操作数最小。观察老鼠的动向,显然老鼠......
  • 【luogu帖】CSP-J 2023 模拟赛 01 赛时答疑帖
    赛时禁止用户与他人交流比赛相关内容,禁止在答疑帖发其他无关内容。欢迎大家参与CSP-J2023模拟赛01。这里是本场比赛的答疑帖。我向各位参赛者及谷友们的支持表示感谢。请不要在赛前在本帖中发布过多灌水相关言论,赛时禁止在本帖中发布灌水相关言论。如果对题面有不理解建议......
  • 【luogu题解】U388218 数数
    数数题目描述给定n个不超过1.5×10⁹的自然数。求这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。输入格式输入的第1行是整数n,表示自然数的个数。第2行到第n+1行每行一个自然数。输出格式输出文件包含m行(m为n个自然数中不相同数的个......
  • luogu P3783 [SDOI2017] 天才黑客
    题面传送门为啥大家都写两个log的线段树优化建边啊,神秘,这1log做法好想又好写捏。首先显然是可以把边看成点的,这样会变成\(O(m)\)个点和\(O(m^2)\)条边,寄。但是还没有完全寄掉,我们发现,对于原图的每个点,对于第一个跑到这个点的边暴力转移,剩下的边转移只有一个子树,否则会......
  • luogu2839题解
    [国家集训队]middle题目分析代码如下。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;typedefunsignedlonglongull;constintMAXN=2e4+10;intx,n,Q,a[MAXN],q[6],root[MAXN],b[MAXN],tot;vector<int>locp[MAXN];structSegmentTreeNode{......
  • luoguP4609 [FJOI2016] 建筑师
    题意:有n个高度1-n的楼房,从右看能看到a个,从左看能看到b个,问楼房有多少种排列方式。分析:首先,高度为n的建筑是肯定不会被挡住的,可以把它作为一个分水岭,在它左边的被左边的建筑挡住,在它右边的被右边的建筑挡住。由此我们可以把所有的建筑分成a+b-1个部分,每个部分由这个部分最高的建......
  • 【luogu题解】T378828 位运算
    位运算题目背景题目由daiyulong20120222创作(me)并由QBW1117完善以及数据。题目描述给定两个数\(x,y\),在给定一个位运算符号\(c\)。请你列出\(x,y\)进行\(c\)位运算是的算数竖式式。注:竖式这么列:显示出两个数的完整二进制,包括前导零。32个'-'。显示出......
  • [Luogu] P7910 [CSP-J 2021] 插入排序
    [CSP-J2021]插入排序-洛谷昨天下午爆肝一下午都没整出来(悲是我太菜了思路第一种想法,暴力即,每次修改操作后重新维护整个数组,时间复杂度\(O(Qn^2)\),能拿52pts但是,想要拿满分,很简单,只需要把排序的双层循环\(n^2\)变为\(n\)即可因为冒泡是对每个点都进行枚举,但是需要修改的......