第2关 - 2018年南海区小学乙组比赛
395.1、禁止标记(stop) 2018NHOI小乙
题目描述
学校举行春游活动,有些地点是禁止学生活动的,老师知道小C是goc编程高手,想让小C用goc软件画一个禁止标记,如下左图所示:
图形是由红色的线粗为10线画出来的,圆的半径为100, 2条直径相互垂直并且左右对称。
题解
本题没有要求使用循环,可以使用四条线重复,也可以两条直径为 200 的重复都可以完成。
int main(){
p.c(1).size(10).o(100);
p.rt(45).fd(100).bk(100).rt(45);
p.rt(45).fd(100).bk(100).rt(45);
p.rt(45).fd(100).bk(100).rt(45);
p.rt(45).fd(100).bk(100).rt(45);
return 0;
}
396.2、三角形(traingle.cpp)2018NHOI小乙
题目描述
在去郊野的路上,小C的同桌小P拿着一个风车玩具迎风跑动,彩色的风车欢快地转动着。小C觉得很漂亮,决定用 goc软件快速的画出来。如下左图所示:
图形每条边长均是100,颜色编号分别是1、2、3。
题解
方法一:双循环
int main(){
for(int i = 1;i<=3;i++){
for(int j = 1; j <= 3; j++){
p.c(j).fd(100).rt(120);
}
p.rt(120);
}
return 0;
}
方法二:单循环+特判
int main(){
int j ;
for(j = 1; j <= 9; j++){
int col = (j-1) % 3 + 1; // 1,2,3
p.c(col).fd(100).rt(120);
if(j % 3 == 0)
p.rt(120);
}
return 0;
}
397.3、柠檬片(lemon)2018NHOI小乙
题目描述
中午野炊时同学们吃着烤肉,需要清凉的柠檬水解渴。为了增加视觉效果,小C把刚才画的三角形组成的风车形状改造了一下,画出了下面的左图的柠檬片:
三角形的边长还是100,它们颜色号是5。
大圆的半径为110,小实心圆的半径为20,它颜色号是13。
但是同学们希望能用指定的N个三角形画出更漂亮的柠檬片,请你协助小C完成任务。
输入格式 一个整数N,范围[2,100]。
输出格式 相应的柠檬片图形。第一个三角形第1条边向上,所有三角形旋转角度相等。
输入/输出例子1
输入:
20
输出:
输入/输出例子2
输入:
5
输出:
题解
int main(){
int n;
cin >> n;
p.c(5);
for(int i = 1; i<=n;i++){
p.fd(100).rt(120);
p.fd(100).rt(120);
p.fd(100).rt(120);
p.rt(360.0 /n);
}
p.c(13).o(110).oo(20);
return 0;
}
398.4、山峰(mountain)2018NHOI小乙
题目描述
等待制作柠檬水的时间是无聊的,大家只能欣赏远处的山脉。
小C觉得可以用N个宽度是20的矩形表示一段远处山脉的高度。比如N=10,高度是50 60 80 70 40 20 55 75 85 90,绘制的图形如下:
可是小P想到“无限风光在险峰”,特别喜欢山峰,希望把表示山峰的矩形里面画个实心的矩形。注意,只有一个高度的左右2边同时都比它矮时,才叫山峰。上面的例子最终的结果是:
**输入格式 ** 第一行:1个整数N,范围是[1,10]。
第二行:N个整数,每个整数范围是[10,200]。
输出格式
相应的图形。矩形的宽是20,高度是输入的山高度,山峰用实心矩形。
输入/输出例子1
输入:
5
40 60 50 70 54
输出:
题解
先存储数据,后进行相邻数判断,首尾可以直接排除。
int arr[15];
int main(){
cinWin();
int n,m;
cin >> n;
// 绘制全部山峰
for(int i = 1;i<=n;i++){
cin >> m;
p.moveTo(i*20,m/2.0).r(20,m);
arr[i] = m;
}
// 排除首尾,画山峰
for(int i = 2; i <= n-1; i++){
m = arr[i];
//p.moveTo(i*20,m/2.0).text(m);
if(arr[i-1] < m && m > arr[i+1]){
p.moveTo(i*20,m/2.0).rr(20,m);
}
}
return 0;
}
399.5、水杯(cup)2018NHOI小乙
题目描述
好消息,柠檬水终于制作好了!一开始柠檬水在红色水杯A里,然后尽量倒入绿色水杯B和青蓝色水杯C中。3水杯的粗细都是一样的(直径都是50),只是高度分别是a、b、c。一开始A水杯是满的,B和C水杯是空的,小C把水杯尽可能的先倒入B;如果B满了后A水杯还有水,就再尽量倒入C水杯。
小C请你用GoC画几个矩形来表示倒水后的每个水杯的高度。例如a=200,b=80,c=100时:
注意:黑色的数字只是表明尺寸,不用画出。
输入格式
第一行,3个整数a,b,c。 范围[10, 200]。输出格式
画出3个水杯,颜色分别是1号、3号、4号,高度分别是a,b,c;用实心的部分表示水的高度;水杯之间距离是10。
输入/输出例子1
输入:
150 80 100
输出:
题解
本题重点要考虑每个杯子是否 满杯。
int main(){
cinWin();
int a,b,c,tmp=0;
cin >> a >> b >> c;
p.up();
// 画 A 杯
p.moveTo(0,a/2.0).r(50,a,1);
tmp = a -b -c;
if(tmp >= 0){
p.moveTo(0, tmp / 2.0).rr(50,tmp,1);
}
// 画 B 杯
p.moveTo(60 ,b/2.0).r(50,b,3);
if(a >= b){
p.moveTo( 60, b / 2.0).rr(50,b,3);
}else{
p.moveTo( 60, a / 2.0).rr(50,a,3);
}
// 画 c 杯
p.moveTo( 120 ,c/2.0).r(50,c,4);
tmp = a -b;
if(tmp >= c){
p.moveTo(120, c / 2.0).rr(50,c,4);
}else if(tmp > 0){
p.moveTo(120, tmp / 2.0).rr(50,tmp,4);
}
return 0;
}
400.6、坐船(board)2018NHOI小乙
题目描述
丰盛的午餐过后,大家准备前往湖心岛游玩。湖边码头上有10条相同型号的小船,每条小船最大承载重量是100;并且每只船上只有2个座位,也就是说一条小船最多能坐2个同学。
运送人的小船用一个矩形加1个或2个圆表示,圆的半径为15。
小C的同伴有N个,他们的体重不一定相同,现在想知道一次运送最多能运多少人?需要最少多少只船?
请把运送人的小船从左向右画出,先画运送一个人的小船,再画运送二个人的小船。
输入格式
第1行:一个整数N,表示人数。范围是[1,20]。第2行:N个整数,每个整数范围是[10,200]。
输出格式
相应的要求图形。矩形个数就是小船的个数,圆个数就是人的个数。
输入/输出例子1
输入:
6
30 80 40 50 70 110
输出:
题解
int arr[25];
int main(){
cinWin();
int n,x,idx=0;
cin >> n;
// 过滤无效数据,并存储 从1开始
while(n--){
cin >> x;
if(x <= 100){
idx ++; // 有效的数组下标
arr[idx] = x;
}
}
// 冒泡排序,由大到小 重量大的优先上船,再补重量小的。
for(int i = 1; i<= idx; i++ ){
for(int j = idx; j > i; j--){
if(arr[j]>arr[j-1]){
int tmp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = tmp;
}
}
}
//测试排序结果
//for(int i = 1; i<= idx; i++){
// cout << arr[i] << " ";
//}
// rIdx 右游标 ,s1 一个人一条船的数量, s2 两个人一条船的数量
int rIdx = idx, s1 = 0, s2=0;
for(int lIdx = 1; lIdx <= idx; lIdx++){
// 左、右游标重合,退出
if(rIdx == lIdx) break;
// 计算两个一条船的情况
if(arr[lIdx] + arr[rIdx] <= 100 && arr[lIdx] != 0){
arr[lIdx] = 0;
arr[rIdx] = 0;
rIdx --;
s2 ++;
}
}
// 遍历剩下的人,即一个人一条船
for(int i = 1; i<= idx; i++){
if(arr[i] > 0) s1 ++;
}
//判断是否超过 10 条船
if(s1+s2 >= 10) s1 = 10 - s2;
cout << s1 << " " << s2 ;
// 开始画图 矩形 宽为 15*2 = 30 ,高为15*4 = 60
int r = 15;
for(int i = 0;i<s1; i++){
p.moveTo(i*30,r).oo(r);
p.moveTo(i*30,r*2).r(30,60);
}
// 要在一人一条船地基础上做偏移后画两个人一条船的图
for(int i = 0;i< s2; i++){
p.moveTo((i+s1)*30,r).oo(r);
p.moveTo((i+s1)*30,r*3).oo(r);
p.moveTo((i+s1)*30,r*2).r(30,60);
}
return 0;
}