5.一个小球从10处落下,每次的弹回之前的高度一半,
请问小球在静止之前一共走过多少距离?
思路
利用循环进行求距离,注意要加上原始的高度。更新值时,用它值本身。
具体实现
#include<stdio.h>
float Desin() {
float sum=0,b;//统计共走的距离,b是每次除后的高度
float high=10;//是初始时的高度
while(high!=0) {
b = high / 2;//每次落下高度的一半
sum += b+high;//累加走的距离
high = high / 2;//更新high的值(方法积累:重点注意下,下次重复这样的可参考)
}
return sum;
}
int main(){
printf("小球静止时候一共走了%f米", Desin());
}
运行结果
小球静止时候一共走了29.999998米
复杂度分析
复杂度分析若分析错,请帮忙看出的大神帮忙指点,这一块很是薄弱。
时间:循坏次数主要与高度有关,高度/2约等于就是高度。所以时间复杂度为O(n),n为高度。 空间:没有用到递归或者是引用额外的数组存储,所以空间复杂度为O(1);
6.我要通过
“答案正确” 是自动判题系统给出的最令人欢喜的回复。本题属于PAT的“答案正确”大派送——只要读入的字符串满足下列条件,系统就输出"“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
1.字符串中必须仅有P、A、T这三种字符,不可以包含其它字符;
2.任意形如xPATx的字符串都可以获得“答案正确”,其中x或者是空字符串,或者是仅由字母A组成的字符串:
3.如果aPbTc是正确的,那么aPbATca也是正确的,其中a、b、c均或者是空字符串,或者是仅由字母A组成的字符串。
现在就请你为PAT写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。
输入格式:
每个测试输入包含1个测试用例。第1行给出一个正整数n(≤10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过100,且不包含空格。
输入样例:
10
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
APT
APAATTAA
输出格式:
每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出YES,否则输出NO
输出样例:
YES
YES
YES
YES
NO
NO
NO
NO
NO
NO
思路
条件2表示 ,只有三个字母,分别是P、A、T时候是正确。
条件2表示,在PAT的前后加上相同个数的A或者不加时正确的。如AAAPATAAA
条件3表示,aPbTc正确,那在PT中间加入一个A,最前边和后边也要分别加入一个A。此处的a、b、c理解为占位符号,他们可以代表A或者是空字符即没有。
总的来说可分为:
1.前后无A型,中间有无数A正确 (相对于P和T来说)
2.前后有A型,后A=前A* 中A
根据条件一知当字符个数小于3时,回答错误。接下来讨论个数大于3个时候。
字符个数大于三个时:
1.记录P、T个数及它们在字符串中最后出现的位置。用other表示除P、A、T三个字符外的字母个数。
2.P和T的个数只有一个时正确。要没有其他字符,所以other要不等于0;(local_T - local_P)表示中间没有数字或者是PT位置相反时候。
3.利用 后A=前A*中A做最后的判断。
具体实现
#include<stdio.h>
#include <string>
#include <iostream>
#include<cstdio>
using namespace std;
//1.前后无A PAT PAAAT
//2.前后有A,后A=前A*中A APATA APAATAA
int main() {
int num;//循坏次数
printf("请输入需要检测的字符串个数\n");
scanf_s("%d", &num);
while (num--) {
char str[201];//定义一个字符数组
str[200] = '\0';//解决strlen(str)的边界警告处理,将最后一位复制为结束;可不用
//printf("请输入需要检测的字符串\n");
scanf_s("%s", str, 201);
int num_P = 0, num_T = 0,other = 0;//num_P表示P的个数,num_T表示T的个数,other表示除了P、A、T三个字符外的的字符个数
int local_P = -1, local_T = -1;//local_P最后一个P的位置,local_T最后一个T的位置
//字符个数小于3时
if (strlen(str) < 3) {
printf("NO\n");
continue;//结束本次循环
}
//字符个数大于3时,对P、A、T分别计算其个数
for (int i = 0; i < strlen(str); i++) {
if (str[i] == 'P') {
num_P++;
local_P = i;//记录P的最后一个位置
}
else if (str[i] == 'T') {
num_T++;
local_T = i;
}
else if (str[i] != 'A') {//除了A之外别的字符,
other++;
}
}
//P和T的个数只有一个,要没有其他字符,所以other要不等于0;(local_T - local_P)中间没有数字或者是PT位置相反时候
if (num_P != 1 || num_T != 1 || other != 0|| (local_T - local_P)<=1) {
printf("NO\n");
continue;
}
//APAATAA 后A=前A*中A
//before_x为P前面A的个数,middle_x为P和T之间的个数,back_x为T到字符串结果的个数
int before_x = local_P, middle_x = local_T - local_P-1, back_x = strlen(str) - local_T - 1;
if (back_x - before_x * (middle_x - 1) == before_x) {
printf("YES\n");
}
else {
printf("NO\n");
}
}
return 0;
}
运行结果
请输入需要检测的字符串个数
10
PAT
YES
PAAT
YES
AAPATAA
YES
AAPAATAAAA
YES
xPATX
NO
PT
NO
WHatever
NO
APPAATAA
NO
APT
NO
APAATTAA
NO
复杂度分析
时间:外层while循环n次,内for也要循环m次,所以时间复杂度为O(n*m); 空间:用到了char的字符数组,因此空间复杂度为数组的大小O(n);
总结
简单的题目有思想,也无法用代码写出来,困难的题目还在是毫无头绪,之前的学习又全部还回去了。
今日收获,学到了scanf() 的用法:scanf这个函数有隐患,所以VS建议使用他们自己开发的scanf_s,如果你要用scanf要去VS里面配置一下。
字符串的输入定义需要用char,而不是string(string是个类对象不能用scanf输入的)。
字符串输入用 %s,而c里面的字符串是char[],用c语音写就要先声明一个char[]
解决C语言的scanf_s()函数问题
本篇代码使用编辑Visual Studio 2022,在使用字符串的输入时报错。因此查阅资料得以解决,资料来源:blog.csdn.net/qq_43309823…
为什么现在要用scanf_s()?
从vc++2005开始,VS系统提供了scanf_s()。在调用该函数时,必须提供一个数字以表明最多读取多少位字符。
很多带“_s”后缀的函数是为了让原版函数更安全,传入一个和参数有关的大小值,避免引用到不存在的元素,有时黑客可以利用原版的不安全性黑掉系统。比如:char d[20];写成scanf_s("%s",d,20);才是正确的,有这个参数20使准确性提高。(百度百科)
如何使用scanf_s()
输入整型时候:
//以下代码没有测试出:结果为2,因为输入两个数a和b
int i, b;
int result;//函数返回值
scanf_s("%d", &i);
scanf_s("%d %d", &i, &b);
result = scanf_s("%d %d", &i, &b);
printf("%d", result);
这是我运行的结果:若有什么地方错误,请大神指出,我没有得出代码内的注释内容;
字符的时候,scanf_s()的安全性就体现出来,:
char d, e[80];
scanf_s("%c %s", &d,1, &e,80);//字符c输入1个,d后面跟1;e字符数组80个,所以e后面加80