【NOIP模拟】机器人

题面

在一个偶然的情况下,你获得了一台3D打印机。
你因此获得了一项殊荣,那就是为玩具公司设计新的机器人。

当然,为了让这个题更加简单(否则怎么能叫水题欢乐赛呢),我们认为,这个机器人是由 Minecra? 里面的方块构成的。如果你不太明白这句话的意思,你可以认为在接下来的过程中,我们都不考虑重力所带来的影响,并且这个机器人全是由正六面体组成。于是,你为这个新的机器人画了一份草图,为了让更加标准化,你画了一个三视图。为了方便计算打印机所用的耗材,你将三视图的面积都分别计算了出来。很不幸的是,你一不小心把这个三视图弄丢了。于是,你的任务是重新构造这个立体图形。如果你,发现无法构造(这肯定是你的垃圾数学把面积算错了),你要悔过并输出我让你输出的东西。这会在下面的输出格式中提到。

输入 ,分别表示三个视图的面积。具体是哪一个请看下面样例解释的图片

方块不受重力影响,且可以不连续

 

分析

构造题,又一次遇到了【上一次是暑假那个无耻的守夜问题,完全不知道怎么构造出来的】

先开始很在意这个正方体,其实发现好瓜啊,完全不必在意正方体,都说了不计重力

于是我就换了一个思路,想是不是让我构造点对,比如4 3 5 这个样例,就是构造4对(x,y),3对(x,y),5对(y,z)

然而每两对之间有限制条件,不是很好构造,每新加入一个数字,都会对两组点对的数量产生影响,除非这个数字以前出现过

这就是我的考场50分做法

就是从0 0 0,每次只改变一个数字,会使两组点对数量增加,当有点对为0的时候,在从以前选到过的中选两个一样的。

比如 1 0 0,1 0 1 ,0 0 1,这三组都选过了,我们选其他数字都会对两组点对数量产生影响,无法处理其他组已经不能再增加数量了,比如3对和4对已经选满了。

但我们可以选 0 1 1啊,这样只会对yz这一对造成影响,上面就是在讲这个意思。其实我觉得好好调一调是能当正解的

但是考场上我是真的没心情调,因为时间花得很厉害。。

100分做法

构造题==钻空子题

我们假设a<b<c,如果不是,swap一下

那么我们可以发现有解当前仅当 a*b>=c(就算a,b毫无重复都没有c那么多的面积,肯定是不合法的)

其实我们只需要构造一个平面图形啊!!!根本不需要三维

意思是,c所在的那一维不管

比如这个图 假设a==3,b==4,c==6,我们只需要构造一条斜线(红色的),不足面积b的地方也补齐(),然后再涂满c这么多面积就行了!!!

粉色的斜线已经粉色的补齐,黄色的是涂满

然后你会发现,这个图形的宽是3,从侧面看是3,长是4,从上面看是4,从正面看面积是6,当然,这是经过交换过后的,我们交换回去就好啦。

代码

#include<bits/stdc++.h>
using namespace std;
int cnt=0;
struct email
{
    int s,id;
}a[5];

inline void print(int x,int y,int z)
{
    int b[3];
    b[a[0].id]=x,b[a[1].id]=y,b[a[2].id]=z;
    printf("%d %d %d\n", b[0], b[1], b[2]);
}
bool cmp(email a,email b){return a.s<b.s;}
int main()
{
    for(int i=0;i<=2;i++)scanf("%d",&a[i].s),a[i].id=2-i;
    sort(a,a+3,cmp);
    if(a[0].s*a[1].s<a[2].s){puts("-1");return 0;}
    printf("%d\n",a[2].s);
    for(int i=1;i<=a[1].s;i++)
        print(i,min(i,a[0].s),0),cnt++;
    for(int i=1;i<=a[1].s&&cnt<a[2].s;i++)
        for(int j=1;j<=a[0].s&&cnt<a[2].s;j++)
            if(j!=min(i,a[0].s))
                print(i,j,0),cnt++;
    return 0;
}

 

posted @ 2018-10-31 20:51  WJEMail  阅读(213)  评论(0编辑  收藏  举报