4、一个小球从10m处落下,每次的弹回之前的一半,请问小球在静止之前一共走过多少距离。
思路
以落下、弹起为一个轮回,累加下落时的高度和弹起时的高度来计算总的结果。
具体实现
#include <stdio.h>
int main() {
float height = 10.0; // 初始高度
float distance = 0.0; // 总共走过的距离
// 循环计算小球弹起和落下的过程
while (height != 0.0) { // 当小球回弹高度为0时停止运动
distance += height; // 累加落下的距离
height /= 2.0; // 计算弹起的高度
distance += height; // 累加弹起的距离
}
printf("小球在静止之前一共走过 %.2f 米\n", distance);
return 0;
}
5、我要通过!
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于PAT的“答案正确”大派送————只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
1.字符串中必须仅有P、A、T这三种字符,不可以包含其他字符;
2.任意形如xPATx的字符串都可以获得“答案正确”,其中x或者是空字符串,或者是仅由字符A组成的字符串。
3.如果aPbTc是正确的,那么aPbATca也是正确的,其中a、b、c均或者是空字符串,或者是仅由字母A组成的字符串。
现在就请你为PAT写一个自动裁判程序,判定那些字符串可以是获得“答案正确”的。
输入格式
每个测试输入包含一个测试用例。第1行给出一个正整数n(10),是需要检测的字符串个数。接下来每个字符串占一行,如果盖子谷川可以获得“答案正确”,则输出YES,否则输出NO。
输出样例:
10
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
Whatever
APAAATAA
APT
APAATTAA
输出样例:
YES
YES
YES
YES
NO
NO
NO
NO
NO
NO
思路
首先理解本题大意:对于给定的字符串,
- 其中必须有且只能有一个“T”和一个“P”,且只能有“T”、“A”和“P”三种字符
- 可以为“
xTAPx”,其中,x为空或者任意多个“A”,且前后两个x相同 - 如果“
aPbTc”满足了上述情况,则aPbATca也是“答案正确”,a、b、c类似上述的x,其中有隐含条件即:PAT为“答案正确”,则PAAT也为“答案正确”,同理,PAAT等都为“答案正确”,所以在判断时不能单纯地认为“P”和“T”中间只有一个“A”
解题思路就是根据要求来一个一个排除不合适的字符串:
- 有2个以上的“P”,或者“T”不符合
- 有除了“P”、“A”和“T”以外的字符不符合
- 没有出现过“P”和“T”的不符合
- “P”和“T”没有依次出现,即“A”在“P”前面,或者“P”和“T”中间没有“A”的不符合
- 不符合“xPATx”的,不符合
- “aPbTc”正确时,不符合“aPbATca”的不符合
具体实现
#include <stdio.h>
#include <string.h>
// 判断字符串是否符合条件
int is_valid(char str[])
{
int p_pos = -1, t_pos = -1, i;
int len = strlen(str);
int count_p = 0, count_t = 0;
// 遍历字符串
for (i = 0; i < len; i++) {
if (str[i] == 'P') {
// 如果之前已经出现过P,就返回NO
if (count_p > 0)
return 0;
p_pos = i;
count_p++;
} else if (str[i] == 'T') {
// 如果之前已经出现过T,就返回NO
if (count_t > 0)
return 0;
t_pos = i;
count_t++;
} else if (str[i] != 'A') {
// 如果出现了其他字符,就返回NO
return 0;
}
}
// 如果没有出现P或T,就返回NO
if (p_pos == -1 || t_pos == -1)
return 0;
// 如果P和T之间没有A,就返回NO
if (t_pos - p_pos <= 1)
return 0;
// 如果最后一个T后面还有A,就返回NO
// 即判断是否是aPbTc的形式,如果T后的A比P前的A少,则一定不符合条件
if (len - t_pos - 1 < p_pos * (t_pos - p_pos - 1))
return 0;
// 判断xPATx的形式
if (p_pos * (t_pos - p_pos - 1) == len - t_pos - 1)
return 1;
// 判断aPbTc和aPbATca的形式
int a_len = p_pos;
int b_len = t_pos - p_pos - 1;
int c_len = len - t_pos - 1 - a_len;
if (a_len * b_len == c_len)
return 1;
// 不符合任何形式,返回NO
return 0;
}
int main()
{
int n, i; // 分别计数字符串个数和循环次数
char str[101];
scanf("%d", &n); // 读入字符串个数
// 循环读入字符串并判断
for (i = 0; i < n; i++) {
scanf("%s", str);
if (is_valid(str)) {
printf("YES\n");
} else {
printf("NO\n");
}
}
return 0;
}
小结
今天的算法第二题略有难度,需要考虑的情况种类很多,特别是“P”和“T”中间不能想当然地认为是只有一个“A”才符合条件,同时也需要大量的时间来进行调试。因为昨天学了一点代码规范,所以在今天的代码风格,笔者自认为还是更加清晰一点的,加油!