第一题
按照题目的要求读取字符串并且解析就可以了,常规的指针操作,活用之前说过的知识
#include <iostream>
using namespace std;
void getDate(int& day, int& month, int& year)
{
// write your code here
string s ;
cin >>s;
day = atoi(s.substr(0,2).c_str());
month = atoi(s.substr(3,2).c_str());
year = atoi(s.substr(6,4).c_str());
}
// dont change main function
int main()
{
int day, month, year;
getDate(day,month,year);
cout<<" "<<day<<" "<<month<<" "<<year<<endl;
return 0;
}
第二题
- 因为是记录字符是否出现,我们其实可以用一个bool数组记录字符是否出现
- 接下来遍历第一个字符串将所有出现字符归零即可
- 归零之后还需要将字符串中间的空字符提出,这块也可以利用快慢指针的想法,fast指针负责判断是否为空,slow指针指向当前的字符应该存放的位置,遍历即可。
#include <iostream>
#include <cstring>
using namespace std;
void deletechar(char* str1, const char* str2) {
// write your code here
int str1Len = strlen(str1);
int str2Len = strlen(str2);
bool record[255] = {0};
char null = '\0';
for(int i = 0;i<str2Len;i++)
record[str2[i]] = true;
for(int i = 0;i<str1Len;i++)
{
if(record[str1[i]])
{
str1[i] = null;
}
}
int slow = 0,fast = 0;
for(;fast < str1Len;fast++)
{
if(str1[fast] != null)
{
str1[slow++] = str1[fast];
}
}
str1[slow] = null;
}
int main() {
char str1[85], str2[85];
cin.getline(str1, 80);
cin.getline(str2, 80);
deletechar(str1, str2);
cout<<str1<<endl;
return 0;
}
第三题
直接用strlen
获取字符串长度,查看最后一个字符是啥返回一个字符串就好,这个应该不用讲解了吧
#include <iostream>
#include <cstring>
using namespace std;
char * reply(const char * sentence)
{
// write your code here
int len = strlen(sentence);
switch(sentence[len-1])
{
case '!': return "Really?!";
case '?': return "Emmmm...";
default: return "Cool.";
}
}
// dont change main function
int main(void) {
char str[1005];
cin.getline(str, 1000);
char * res = reply(str);
if (res) cout << res << endl;
delete [] res;
return 0;
}
第四题
这题思想上不难,但是需要注意的细节有很多,在这里我只阐述我的算法,同学们可以参考这个思路按照自己的想法实现
- 首先这个题目大致要写两个函数,一个用于排序的函数和一个用于比较的函数(如果用的是char数组的写法,则还需要一个交换的函数)
- 排序的函数多种多样,冒泡,插入,甚至是快排同学都可以自己尝试一下,弄清楚思路之后就不难实现了
- 比较的函数实现的是两个字符串之间的比较(假定s1小于s2等于返回true,否则返回false),我们用一个遍历存放下字符串中较短的那个字符串的长度,随后遍历一下,看看前面这块是否有不同,都相同则依据长度返回结果即可
这样这个题目就算完成了,卡了比较久的同学可以思考一下自己还有哪可以优化的地方
#include <iostream>
#include <cstring>
using namespace std;
bool compare(string str1,string str2)
{
int l1=str1.length();
int l2=str2.length();
int min=l1<l2?l1:l2;
for(int i=0;i<min;i++)
{
if(str1[i]>str2[i])
return true;
if(str2[i]>str1[i])
return false;
}
if(l1>l2)
return true;
else
return false;
}
void swap(string&str1,string&str2)
{
string temp=str1;
str1=str2;
str2=temp;
}
void quickSort(string*arr,int start,int end)
{
int i=start,j=end;
if(start>=end) return;
string standard=arr[end];
while(i<j)
{
while(i<j&&compare(arr[i],standard))
i++;
while(i<j&&!compare(arr[j],standard))
j--;
swap(arr[i],arr[j]);
}
swap(arr[i],arr[end]);
quickSort(arr,start,i-1);
quickSort(arr,i+1,end);
}
int main()
{
int n=0;
cin>>n;
string arr[n];
for(int i=0;i<n;i++)
cin>>arr[i];
quickSort(arr,0,n-1);
for(int i=0;i<n;i++)
cout<<arr[i]<<endl;
return 0;
}
第五关
这个题目说白了就是变种的斐波那契数列,一颗高度为n的树如果是最小平衡二叉树,那么它的左右子树一定也是最小平衡二叉树,这样用f(n)代表高度为n的最小平衡二叉树结点数量,则有
f
(
n
)
=
f
(
n
−
1
)
+
f
(
n
−
2
)
+
1
f(n) = f(n-1)+f(n-2)+1
f(n)=f(n−1)+f(n−2)+1
其中 f(n-1)+f(n-2)
分别代表左右子树的结点数,这样一来不管是递归还是循环都能很快完成.
#include<bits/stdc++.h>//万能头文件,几乎包括c++所有库函数
using namespace std;
int tree(int h)
{
if(h==1)
return 1;
if(h==2)
return 2;
int ans=tree(h-1)+tree(h-2)+1;
return ans;
}
int main() {
int h=0;
cin>>h;
int ans=tree(h);
cout<<ans;
}
第六题
这个题目直接用double来做并设置好精确度就可以直接通过测试,但是如果碰到小数点后长度较多的情况也是不能过的,所以更加建议的做法是将输入视为字符串。
- 将输入字符分为两种情况,一种比1大,这个时候判断有没有小数点从而找出有几位有效数字即可,也就是从后往前找到第一个非0的数字,再依据小数点(如果有)的位置判定有几位有效数字即可
- 另一种就是比1小,这个时候找到小数点后第一个非零数字即可,这个时候是从后往前进行遍历
#include<bits/stdc++.h>//万能头文件,几乎包括c++所有库函数
using namespace std;
int main() {
string str;
cin>>str;
int l=str.length();
int l1=l,l2=0;
bool flag=false;
string str1="";
for(int i=0;i<l;i++)
{
if(str[i]!='.'&&(flag||str[i]!='0'))
{
str1+=str[i];
if(!flag)
{
if(i<l-1)
str1+='.';
l2=i;
}
flag=true;
}
if(str[i]=='.')
l1=i;
}
int len=str1.length()-1;
while(str1[len]=='0')
{
str1[len]='\0';
len--;
}
cout<<str1;
int k=l1-l2;
if(l1>l2)
k--;
cout<<'e'<<k;
}