2018 华南师范大学软件学院蓝桥杯 18 级预选赛于 2018 年 11 月 22 日并不怎么成功地举行,共有 273 名同学有效参赛(提交过代码),115 人 AC 1 题以上,最高过题数为 4 题,共 3 人。
前言
本次比赛仅供软院 18 级参加,入门难度。
语法难度层级上升至数组范围。//也就是啥都可以出了
题解
A.The odd integer
Description
做完上次在 1 1 1- 10 10 10 中找缺少的整数的任务后,小 z 觉得太简单了,很无聊……今天,他又接到一个新任务。这次出现的整数不只是 1 1 1- 10 10 10 了,范围扩大到 0 0 0- 1000 1000 1000,但是并不是所有的整数都会出现,有的整数会出现多次,有的整数干脆不出现。而且这些出现的整数还有一个规律,在给定的 n n n 个整数中,只有一个整数出现了奇数次,其他整数都出现了偶数次。现在让你找出这个出现奇数次的整数。
Input
第一个数字 m m m,表示接下来有 m m m 行输入。接下来 m m m 行,第一个数字 n n n,表示给你 n n n 个整数,后面跟上这 n n n 个整数。( 1 ≤ m ≤ 10 , 1 ≤ n ≤ 3000 1 \le m \le 10,1 \le n \le 3000 1≤m≤10,1≤n≤3000),并且这 n n n 个整数都在 0 0 0- 1000 1000 1000 之间。
Output
有 m m m 行,每行按照参考样例的输出进行。
Sample Input
2
7 10 15 16 17 16 15 10
11 123 456 456 456 123 999 999 500 100 100 500
Sample Output
No1. The odd integer is: 17.
No2. The odd integer is: 456.
参考思路
这道题用数组做比较简单,整数范围在0-1000,数组也不会开太大。数组的作用:统计各个整数出现的次数,数组下标即表示对应整数。所以一开始应该先初始化为0,而且不止一组数据,每次应该把数值重新初始为0。之后遍历数组找出数值为奇数的值,对应下标就是答案。
参考代码
#include<stdio.h>
int main()
{
int a[1010]; // range is from 0 to 1000
int m,n;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
memset(a,0,sizeof(a)); // initial the array
scanf("%d",&n);
while(n--)
{
int temp;
scanf("%d",&temp);
a[temp]++;
}
for(int j=0;j<=1000;j++)
{
if(a[j]%2)
{
printf("No%d. The odd integer is: %d.\n",i,j);
break;
}
}
}
return 0;
}
易错点解析
- 看题不仔细。最为明显的一个地方就是输出语句格式与题意不符,这里少个空格那里少个冒号,前面打成大写 O 后面打成中文冒号。最为妥当的一个方法就是把样例输出中的语句复制到程序中,对动态的数据再进行相应的更改。另外还有一些偶数次=出现 2 次和奇数次=出现 1 次的错误理解。
- 一牵涉到数组就必定有的数组越界。虽然已经不是第一次大开眼界了(是第二次//逃),但看到各种明明数据 1 e 3 1e3 1e3 数组还是开个 10 10 10 的到处蹭的代码还是觉得……嗯,可爱。
- 算法问题。标程标解中给到的是 O ( m a x ( n ) ) O(max(n)) O(max(n)) 的做法,事实上也有不少 AC 代码用的是对每个数寻找当前数组内相同的数的个数的 O ( n ) O(n) O(n) 做法,这也是出题组给过的做法。所以当看到某些神奇的 O ( m n ∗ r a n g e ( n ) ) O(mn*range(n)) O(mn∗range(n)) 以及甚至排了个序的做法时,本蒟蒻还是觉得非常震惊的。(事实上排序并不是不行,只是这位兄 dei 没有处理好边界条件)
- 代码实现细节。比较明显的是在各组数据间没有进行数组的初始化,另外还有一些奇偶不分、忘记 a[0] 处的值、% 打成了 / 以及数据组间没有换行的细节没有处理好。
B.又找女朋友
Description
FS 上次自己探索找女朋友并没有成功,于是他找到了已经脱单了的 SLF 帮他总结一下。身经百战见得多的 SLF 告诉他搭讪不能有那么强的目的性,但是也需要投其所好。
SLF 仍然和上次一样把这个模型解释为一个足够大的地图,FS 和他心仪的女生分别在点 ( x 1 , y 1 ) (x1,y1) (x1,y1) 和 ( x 2 , y 2 ) (x2,y2) (x2,y2) 上。FS 搭讪的时间为 T T T,在每个单位时间里,FS 将会抛出一个话题,这个话题将生成一阵风(东南西北),FS 可以选择顺风偏移一个单位或者留在原地,若 FS 最终能到达女生所在的位置则视为脱单。
FS 是个非常追求效率的人,他想知道自己至少需要花费多少时间就可以脱单,但是他觉得背 SLF 帮他准备的话题已经非常烧脑和麻烦了,于是想请你帮忙计算他到底可以多早脱单。
Input
第一行两个正整数 x 1 , y 1 x1,y1 x1,y1,表示 FS 的所在位置。
第二行两个正整数 x 2 , y 2 x2,y2 x2,y2,表示女生的所在位置。
( 1 ≤ x 1 , y 1 , x 2 , y 2 ≤ 1 e 9 ) (1 \le x1,y1,x2,y2 \le 1e9) (1≤x1,y1,x2,y2≤1e9)
第三行一个正整数 T T T,表示 T T T 个时刻。 ( 1 ≤ T ≤ 1 e 6 ) (1 \le T \le 1e6) (1≤T≤1e6)
接下来 T T T 行,每行一个字符,表示 FS 抛出的话题造成的风向,用东南西北的英文单词的首字母表示。
Output
输出 FS 脱单最少需要的时间。如果 FS 无法脱单,则输出 “Single dog!”(不含引号)。
Sample Input
1 1
2 2
5
E
N
W
W
N
Sample Output
3
参考思路
题意要求至少花费的时间,故应用规划求解,又因为每一步是独立的且刮风时可走可不走,可推得在某步决策时,能缩短与目标点的距离就走,否则不走(走则需再花费一个时间进行恢复),即证得贪心。根据高中地理必修一课本,风向等于风的来向,可得刮东风时顺风应向西走,其它相似。
参考代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
char ch;
int x1,x2,y1,y2,t;
int main(void)
{
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&t);
if(x1==x2 && y1==y2)
{
printf("0\n");
return 0;
}
for<