竞赛总览
CSDN 编程竞赛二十七期:比赛详情 (csdn.net)
四道题都不难,本来十分钟内就可以解决,但是这次竞赛bug比较多,体验不是很好。
竞赛题解
题目1、幸运数字
小艺定义一个幸运数字的标准包含三条:1、仅包含4或7。2、幸运数字的前半部分数字之和等于后半部分数字之和。3、数字的长度是偶数。
std::string match (std::string& str) {
int len = str.length ();
if (len % 2 != 0) return "No";
for (int i = 0; i < len; i++) {
if (str [i] != '4' && str [i] != '7') return "No";
}
int sum [2] = {0, 0};
for (int i = 0, j = len / 2; i < j; i++) {
sum [0] += str [i];
sum [1] += str [i + j];
}
return sum [0] == sum [1] ? "Yes" : "No";
}
先用规律1和规律3:仅包含4或7,数字的长度是偶数。
匹配失败直接返回假,否则再用规律2进行匹配。
这道题的bug是返回Yes时字母是全部大写的,而No只有首字母是大写的。博主提交之后发现只通过了40%的测试数据,于是改了数据中的几个No,发现通过的都是No的测试数据,没有Yes。于是尝试修改Yes,结果通过了此题。
题目2、投篮
小明投篮,罚球线投球可得1分,在三分线内投篮得分可以得到2分,在三分线以外的地方投篮得分可以得到3分,连续投进得分累计,一旦有一个球没投进则得分清零,重新计算。现给出所有得分记录(清零不计入得分),请你计算一下小明最多连续投进多少个球?
int main () {
int result = 0;
int n; scanf ("%d", &n);
int data [n]; for (int i = 0; i < n; i++) scanf ("%d", &data [i]);
int num = 1;
for (int i = 1; i < n; i++) {
if (data [i] > data [i - 1]) num += 1;
else {
if (result < num) result = num;
num = 1;
continue;
}
}
return 0;
}
这道题似乎也有些问题,从题目描述上看,如果一直得零分,应该是连续投进零个球。
然而,提交之后发现答案错误,于是改成从1开始计数,竟然通过了。
使用循环来统计最多投球情况。输出答案之前,还要单独再判断一次统计结果。
题目3、通货膨胀-x国货币
X国发行货币最高面额为n。次高面额为n的因子。以此类推。X国最多发行多少种货币。
int calc (int n) {
int result = 1;
for (int i = 2; n > 1; i++) {
while (n % i == 0) {
n /= i;
result += 1;
}
}
return result;
}
这道题同样有些问题,货币面额竟然可以重复,可能题目意思是取因子之后用剩余数字作为新的n进行计算。但题目描述过于简单,不知道真的是这个意思还是题目的bug。
题目4、最后一位
小明选择了一个正整数X,然后把它写在黑板上。然后每一天他会擦掉当前数字的最后一位,直到他擦掉所有数位。在整个过程中,小明会把所有在黑板上出现过的数字记录下来,然后求出他们的总和sum。例如X = 509,在黑板上出现过的数字依次是509, 50, 5,他们的和就是564。小明现在给出一个sum,小明想让你求出一个正整数X经过上述过程的结果是sum。
int main () {
int sum; scanf ("%d", &sum);
for (int i = 0; i <= sum; i++) {
if (calc (i) == sum) {
printf ("%d", i);
break;
}
}
return 0;
}
不难看出,一个数的sum一定比这个数本身大,所以结果就在0到sum之间。
测试数据比较水,直接使用暴力模拟法,即可通过此题。