第9关 - 2017佛山图书馆GoC决赛试题

173.(佛山图书馆GoC决赛试题 )第1题:五个方形(five)

题目描述

小P刚学会goc时最喜画正方形拼成的图形,请编程画出如下图形。

image.png

注意:上图的每个线段长度都是50。

题解

这道题主要考查图形分解,最简洁的是看到两个长方型旋转叠加。。

也可以成 4 个正方形 ,围绕中间的正方型旋转。

int main(){
    
    p.r(150,50,2).r(50,150,2);
    return 0;
}

174.(佛山图书馆GoC决赛试题 )第2题 眼镜(glasses)

题目描述

小P设计了如下图的“眼镜”,请你帮忙使用GoC编程绘制。

image.png

注意:眼镜黑心圆半径为10,外圆半径为40,眼镜架长度100、斜了45度。

题解

int main(){
    p.up()
        .o(40,2).oo(10,0)
        .fd(40)
        .down()
        .rt(45).fd(100);
    
    p.moveTo(80,0)
        .up().lt(45)
        .o(40,2).oo(10,0)
        .fd(40)
        .down()
        .rt(45).fd(100);
    
    
    return 0;
}

175.(佛山图书馆GoC决赛试题 )第3题:小树(tree)

题目描述

小P现在学会使用颜色命令,他使用2种新的颜色:棕色(6号)和绿色(3号)设计了如下图的“小树”,当然为了可变,图中正三角形的个数n和线段长度a是输入的,请你帮忙使用GoC编程绘制。

image.png

注意:所有线段长度都一样。

输入格式 一行:2个正整数n和a。

输出格式 相应的图形。

输入/输出例子1

输入:

1 50

输出:

image.png

输入/输出例子2

输入:

5 20

输出:

image.png

题解

int main(){
    
    int n,a;
    cin >> n>>a;
    p.c(6).fd(a);
    p.c(3).rt(90);
    
    for(int i=1;i<=n;i++){
        p.bk(a/2.0);
        for(int j= 1;j<=3;j++){
            p.fd(a).lt(120);
        }
        // 返回三角形顶点
        p.rt(120).bk(a).lt(120);
    }
    
    return 0;
}

176.(佛山图书馆GoC决赛试题 )第4题:雪花(snow)

题目描述

小pen正在研究一种特殊的雪花:

image.png

研究发现,它们都是由一些边长为30 的小“叉”组成的,第1个图有4个小叉,第2个图有5个小叉,第3个图有8个小叉。 小pen浪浪的想,不仅要有不同的小叉个数,还应该配上2种颜色间隔的画才好看。比如输入小叉个数n=6,两种颜色号a=3、b=4,画出的图如下:

image.png

注意:所有线段长度都一样为50。

输入格式 一行:3个正整数n和a、b。

输出格式 相应的图形。

输入/输出例子1

输入:

10 3 6

输出:

image.png

输入/输出例子2

输入:

16 9 11

输出:

image.png

题解

int main(){
    
    int n,a,b;
    cin >> n >> a >> b;
    for(int i=0;i<n;i++){
        if(i%2==0) p.c(a);
        else p.c(b);
        
        p.fd(50).lt(45).fd(50).bk(50)
            .rt(90).fd(50).bk(50).lt(45)
            .fd(50).bk(100);
        p.rt(360.0/n);
    }
    return 0;
}

177.(佛山图书馆GoC决赛试题 )第5题 同心圆(cir)

题目描述

小Pen上数学辅导课,内容是等差数列,就是一系列数,每相邻的2项之间的差都相等(后项-前项)。 比如下面三个数列都是等差数列: 1 2 3 4 5 6….; 10 13 16 19 22….; 100 95 90 85 80 …. 小Pen一听就“秒懂”了,无聊时他就喜欢画100个同心圆,第1个圆半径是1,第2个圆半径是2,第3个圆半径是3,….。结果如下图:

image.png

这时数学老师提问,如果给定等差数列的第1项和第100项,你能不能写出所有的中间项?小Pen瞬间有了联想:能不能用100个圆来表示这100项数列呢? 就用等差数列的数值当颜色的RGB值!数列的第1项当半径为1圆的颜色RGB、数列的第2项当半径为2圆的颜色RGB、数列的第3项当半径为3圆的颜色RGB、…。

  • 提示:RGB值x变为goc的颜色命令为:pen.rgb(x%256, x/256%256, x/256/256).c(16);

例如:第1项是50,第100项是248,画出的是:

image.png

输入格式 一行2个正整数a,b范围[1,10000000]。a表示数列的第1项,b表示数列的第100项。

输出格式 相应的图形。

输入/输出例子1

输入:

500 104

输出:

image.png

输入/输出例子2

输入:

500000 500297

输出:

image.png

题解

方法一:从里向外画圆

int main(){
    int n,a,b,d;
    cin >> a >> b;
    n= 100;
    // 计算每个间隔的距离
    d=(b-a)/(n-1);
    
    for(int i=1;i<=n;i++){
        p.rgb(a%256,a/256%256,a/256/256).c(16);
        p.o(i);
        a+=d;
    }
    
    return 0;
}

方法二:从外向里画圆

int main(){
    int n,a,b,d;
    cin >> a >> b;
    n= 100;
    d=(b-a)/(n-1);
    p.speed(1);
    while(n--){
        p.rgb(b%256,b/256%256,b/256/256).c(16);
        p.o(n);
        b -=d;
    }
    
    return 0;
}

178.(佛山图书馆GoC决赛试题 )第6题:靠近(close)

题目描述

小pen有4个正方形,1个红色(1号颜色)正方形、1个黑色(0号颜色)正方形、1个紫色(11号颜色)正方形和1个绿色(10号颜色)正方形,他把红色放在上面黑色放在下面对齐组成左边一对,把紫色放在上面绿色放在下面对齐组成右边一对,两个的下面都在“地面上”。例如下图是4个边长分别是40 20 30 60的情况下画出的图形:

image.png

现在,小pen想让左右两对图形不改变形状的前提下尽量靠近,例如上面的图靠近后就变为:

image.png

输入格式 一行4个正整数a、b、c、d,范围都在[10,100]。分别表示红色正方形、黑色正方形、紫色正方形和绿色正方形的边长。

输出格式 相应的图形。

输入/输出例子1

输入:

70 50 20 10

输出:

image.png

输入/输出例子2

输入:

50 30 20 28

输出:

image.png

题解

方法一:

int a,b,c,d;

int pdL() //计算绿色能靠近多少
{
    int min=b/2;
    if ( d>b && a>b){ // D高了
        min=a/2;
    }
    min += d / 2;
    cout << min;
    return min;
}

int pdR() // //计算紫色能靠近多少
{
    int min = b / 2;
    if (d >= b && d < a + b)
        min = a / 2;
    else if (d < b && c + d > b && a > b)
        min = a / 2;
    min += c / 2;
    cout << min;
    return min;
}

int main()
{    
    cin >>a>>b>>c>>d;
    p.up()
        .fd(b/2).rr(b,b,0)
        .fd(b/2+a/2).rr(a,a,1);

    int xx=pdL();
    int yy=pdR();
    if (xx<yy) xx=yy;
    
    p.moveTo( xx ,0)
        .fd(d/2).rr(d,d,10)
        .fd(d/2+c/2).rr(c,c,11);

    return 0;
}

方法二:

int a,b,c,d;

void draw(int a,int b,int c1, int c2)  //画一对
{
	p.up()
            .fd(b/2). down()
            .rr(b,b,c1).up()
            .fd(b/2+a/2).down()
            .rr(a,a,c2).up()
            .bk(a/2+b);
}
int pd1() //计算绿色能靠近多少
{
	int min=b/2;
	if ( d>b )   //d高了
	{
            if (a>b) min=a/2;
	}
	cout << min+d/2;
	return min+d/2;
}

int pd2() //计算紫色能靠近多少
{
	int min=0;
	if ( d<b )   //d矮了
	{
	  min=b/2;
	  if ( c+d>b) //也碰到红色的
	   if (a>b) min =a/2;
	}
	else 	 
	{
            if (d <a+b)
                min=a/2;
	}
	cout << min+c/2;
	return min+c/2;
}
int main()
{    
    cin >>a>>b>>c>>d;
    draw(a,b,0,1);	 
     int xx=pd1();
     int yy=pd2();
     if (xx<yy) xx=yy;
	 p.moveTo( xx ,0);
	 draw(c,d,10,11);
	 
    return 0;
}