COCI CONTEST #3 29.11.2014 T3 SILUETA

来源:互联网 发布:flash插件 mac 编辑:程序博客网 时间:2024/06/07 23:34

第三题:
题目描述
有一个画家,画了n栋摩天大楼。(实际上只有远远望去的轮廓)。每栋楼都是一个矩形,有些矩形是重叠在一起的。所有的矩形的底边都在一条直线上。很不幸,画被烧毁了。但是记得每个矩形的位置和高度,现在请你复原这幅画,并求出矩形的轮廓线的周长(不包含底边)。
输入
第一行:给出一个整数n表示有n栋大楼。(n<10000)
接下来有n行,每行三个整数Li,Ri,Hi。表示第i栋楼的左下角坐标为(Li,0),右上角坐标为(Ri,Hi)。(1<=Li,Ri,Hi<=1000,3<=Ri-Li<=1000)
输出
第一行为一个整数,表示摩天大楼的周长。
接下来h+1行,为复原的地图。
其中h表示最高的那栋楼的高度。
‘#’表示摩天大楼的轮廓,其中x轴用‘*’表示,其他区域用’.’表示。具体看样例。
样例输入
3
1 5 4
7 11 3
9 13 5
样例输出
28
这里写图片描述
一般难度。
可以预处理一个h[],h[i]表示当x=i时,y最大是多少。
如样例,h[]的值应该是
i 1 2 3 4 5 6 7 8 9 10 11 12
h[i] 4 4 4 4 0 0 3 3 5 5 5 5
然后扫一遍h[i]数组。
对于一个i,如果h[i]不为0,那么在对应的高度输出#号。
如果h[i-1]比h[i]低,那么应该在i处从h[i-1]的高度一直输出#直到高度变为h[i]-1。
如果h[i-1]比h[i]高,那么应该在i-1处从h[i]的高度一直输出#直到高度变为h[i-1]-1。
有一个神奇的现象,如果像我刚才那样输出#,那么每输出一个#,ans++,周长就是ans。
其实应该这样:
扫一遍图案,每有一个#,ans++;每有一个外凸的角,ans++;每有一个内凹的角,ans–。
或者搜索也可以。
30分。
因为求错周长了。
考试的时候以为所有的不规则图形都是可以平移边,变成一个规则矩形的周长
但是只有阶梯状的是这样,内凹的不是。
而样例全是阶梯状的。。。

#include<iostream>#include<cstdio>using namespace std;bool map[1005][1005];int h[1005],minl=1005,maxr,maxh,n,ans;int main(){    scanf("%d",&n);    for(int i=0;i<n;++i)    {        int li,ri,hi;        scanf("%d%d%d",&li,&ri,&hi);        minl=min(li,minl);        maxr=max(ri,maxr);        maxh=max(hi,maxh);        for(int i=li;i<ri;++i)            h[i]=max(h[i],hi);    }    for(int i=minl;i<=maxr;++i)    {        if(h[i])map[h[i]][i]=1,ans++;        if(h[i]>h[i-1])            for(int j=h[i-1];j<h[i];++j)                map[j][i]=1,ans++;        if(h[i]<h[i-1])            for(int j=h[i];j<h[i-1];++j)                map[j][i-1]=1,ans++;    }    printf("%d\n",ans);    for(int i=maxh;i>=0;--i)    {        for(int j=minl;j<maxr;++j)            i==0?printf("*"):printf("%c",map[i][j]?'#':'.');        puts("");    }}
0 0
原创粉丝点击