国庆作业进阶题解析

第一题

这一题直接按照题目的要求对输入分情况处理就好,这个没啥思维上的难点,注意不要写出80<x<100这样的错误表达式就好

#include<iostream>

using namespace std;
int main() 
{
    int score;
    cin >> score;
    switch(score/10){
        case 10: cout << 'A';
        break;
        case 9: cout << 'A';
        break;
        case 8: cout << 'B';
        break;
        case 7: cout << 'C';
        break;
        case 6: cout << 'D';
        break;
        default: cout << 'E';
    }
  return 0;
}

第二题

元音字母只有5个,判断输入的字母是否在元音对应的5个字符之内就好,这个就是if的判断条件比较长,要想两个判定条件同时满足,可以用if(条件1&&条件2)的这种格式`

#include<iostream>
using namespace std;
int main() 
{
    char a;
    cin >> a;
    if(a=='a'||a=='e'||a=='i'||a=='o'||a=='u')
        cout << "vowel";
    else
        cout << "consonant";
  return 0;
}

第三题

比大小这个可用用这样的思路去解释,从已经算过的数字中拿出一个最大的数字,拿它去和当前的数字比大小,从而得到一个包含当前正在比较数字在内的集合集合中最大的数字,如此循环就可得到所有数字中最大的数字,当然这里只有三个数字怎么算都可以啦

#include<iostream>

using namespace std;
int main() 
{
    int a,b,c,max,mid,min;
    cin >> a >> b >> c;
    if(a>b){
        max=a;
        min=b;
        if(c>a){
            max=c;
            mid=a;
        }
        else if(c<b){
            mid=b;
            min=c;
        }
        else
        mid=c;
    }
    else{
        max=b;
        min=a;
        if(c>b){
            max=c;
            mid=b;
        }
        else if(c<a){
            mid=a;
            min=c;
        }
        else
            mid=c;
    }
    cout << min <<" "<<mid<<" "<<max;
  return 0;
}

第四题

这个没啥好说的,思路上和第一题基本上是一致的

#include<iostream>

using namespace std;
int main() 
{
    double a;
    cin >> a;
    if(a<=10)
        cout << 1.5*a;
    else
        cout << 15+2*(a-10);
  return 0;
}

第五题

这个题目熟悉ascii码的话可用直接用读取的数据进行加减就好,可以看看islower()isupper()这两个函数,对应的头文件是cctype,另外还有tolowertoupper这两个转换函数,可以多去了解一下cctype这个头文件

#include<iostream>

using namespace std;
int main() 
{
    char a;
    int ascii=0;
    cin >> a;
    if((int)a<=90&&(int)a>=65) {
        ascii=(int)a+32;
        cout << (char)ascii;
    }
    else if((int)a<=122&&(int)a>=97){
        ascii=(int)a-32;
        cout << (char)ascii;
    }
    else
        cout<<a;
  return 0;
}

第六题

这个题目和第一题是同类型的,针对不同的类型进行分析即可

#include<iostream>

using namespace std;
int main() 
{
    char type;
    int i,o;
    cin >> type >> i >> o;
    switch(type){
        case 'c':{
            if((o-i)<=3)
                cout << 5*(o-i);
            else
                cout << 15+10*(o-i-3);
        }
        break;
        case 'b':{
            if((o-i)<=2)
                cout << 10*(o-i);
            else
                cout << 20+15*(o-i-2);
        }
        break;
        case 't':{
            if((o-i)<=1)
                cout << 10*(o-i);
            else
                cout << 10+15*(o-i-1);
        }
        break;
    }
  return 0;
}

第七题

这个题目其实就是展示一下双指针的算法思路。首先明确一点,我们的目标是什么呢?找出所有不同的相反数对的数量,那么很显然,如果是原来没有排序的数组,我们基本上没有什么很好的思路,只能从头遍历到尾,再一遍遍找数组所有数字中中有没有和它对应的相反数,再去掉重复的数字对,自然我们就想到将数组排一下序,这样就可以依据大小关系省去提前结束查找过程,这是第一步问题,怎么找到当前数字对应的相反数,当然循环查找的过程是不可以省略的。

从上面的论证过程中,我们已经有的思路什么?答案是
1.数组排序
2.指针一从头开始遍历数组,指针而从尾开始寻求当前数字对应的相反数这里的一个小技巧就是,我们需要每次从右边开始找起吗(也就是写第二个循环寻找相反数)?但是是不需要,因为数组已经拍好序了,所以当我们找到元素s【i】对应的相反数s【j】的时候,s【i+1】的相反数s【k】一定满足k<=j,严格论证挺简单的,同学可以自己试一下,这样总共就只需要一个循环就可以查找完毕,就如下图一样从两边往中间靠拢
在这里插入图片描述

解决了如何找到相反数的问题 ,接下来就是要保证无重复,这个问题其实也很好解决,既然,已经拍好序,那么只需要将指针一致移动到下一个位置,直到满足指针指向位置的元素和之前的不一样就好,注意数组指针越界的问题

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
    int n;
    int a[10];
    cin>>n;
    for (int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    sort(a,a+n);
    int is=0,ie=n-1;
    int num=0;
    while (is<ie)
    {
        if (a[is]+a[ie]==0)
        {
            num++;
            while(ie>0 && a[ie-1]==a[ie]) ie--;ie--;
            while(is<n-1 && a[is]==a[is+1]) is++;is++;
        }
        else if (a[is]+a[ie]<0)
        {
            is++;
        }
        else
        {
            ie--;
        }
    }
    cout<<num<<endl;
}

第八题

这个其实还是很好理解的,有多种办法可以解答,可以复用上面提到的双指针思想,只不过目标从找相反数变为了寻找连续子序列的长度,伪代码的话大概是这样

while(i<n)
{
	int j=i+1;
	for(;j<n;j++)
	{
		//如果当前元素不再等于上一个元素再加一,则退出循环
	}
	curLen = j-i;
	maxLen=max(curLen, maxLen);
}

但是这里限制了数据的范围,所以其实可以提供另外一个解题思路,那就是计数方法,很简单,另一个bool数组b长度为数据的范围,初值为flase,当数组a中存在某个数字n的时候,b【n】修改为true,最后循环查找b这个数组中最长的连续序列的长度

#include <iostream>

using namespace std;

int main()
{
    int a[20];
    int n;
    cin>>n;
    for (int i=0;i<n;i++) cin>>a[i];
    int b[1000]={0};
    int max_l=0;

    for (int i=0;i<n;i++)
    {
        b[a[i]]=1;
    }

    for (int i=0;i<1000;i++)
    {
        if (b[i]==1)
        {
            int l=1;
            while (i<999 && b[i+1]==1)
            {
                i++;
                l++;
            }
            i++;
          
            if (l>max_l) max_l=l;
        }
    } 

    cout<<max_l<<endl;
}

第九题

这个题目思路其实应该是比较清晰的,针对输入进来的字符的类型进行判断,如果是字母字符,分情况讨论,如果是大写字符,那么它要么是句子的第一个大写字符,直接输出就好,要么是其他单词的开头,则输出一个空格并且将其输出,如果是小写字符,直接输出就好。如果输入的是句子的结尾符号,输出符号之后还应该输出一个换行符号,难点在于按照题目的意思把思路捋顺,代码还是很好写的

#include<iostream>
#include<algorithm>
using namespace std;
int main() 
{
    string str ;
    cin >>str;
    int index =0;
    bool isNewSentence = true;
    while(index <str.length())
    {
        if(str[index]<='Z'&&str[index]>='A')
        {
            if(isNewSentence)
            {
                isNewSentence = false;
                cout <<str[index];
            }
            else
            {
                cout <<" "<<(char)(str[index]+32);
            }
        }
        else if (str[index]=='.'||str[index]=='!'||str[index]=='?')
        {
            cout <<str[index]<<endl;
            isNewSentence =true; 
        }
        else
        {
             cout <<str[index];
        }
        index++;
    }
   cout <<endl;
  return 0;
}

第十题

这个题目有两种思路,第一种就是每次遇到计算符号进行一次判断,在遇到符号的时候,我们已经知道的条件应该有这么几个,该符号之前的最后一个符号operation是什么,operation的位置,operation左边的数字字符串,已经计算到的结果sum,那么思路就是
s u m = s u m ( o p e r a t i o n ) 右边的数字 sum=sum (operation) 右边的数字 sum=sum(operation)右边的数字
按照上面这个公式一路计算过去即可,但是这里存在几个问题,首先是第一个符号该怎么计算,很容易想到我们将sum初值设置为0,operation设置为加号即可,这样不会影响第一个符号的计算,另外一个问题就是按照这个思路最后一个符号将不会被计算,所以需要在结尾多加一个判断,但是更加有技巧的做法是什么呢,直接在原来的字符串后面拼接上一个计算符号即可

但是更加有效率的方法是什么呢?直接通过指针计算,很简单的思想是只在遍历过程种每次判读字符的类型是什么,如果是数字,说明需要计算,那么依据上一个操作符号将从当前字符对应的数字提取出来计算就好,那么怎么解决重复计算的问题呢,答案是直接将遍历过程使用的指针的值修改,跳过对应的数字,如果是计算符号,只需要记录其类型再将指针移动就好,简而言之,将原本由for循环执行的数组遍历指针操作转而由自己执行。

#include<iostream>
using namespace std;
int main() 
{
// 请在下方添加代码
/********** Begin *********/
  string str ;
  cin >>str;
  int index=0;
  int j=0;
  float ret = 0.0;
  float current =0.0;
  bool isAdd = true; 
  for(int i=0;i<str.length();)
  {
      if(str[i]=='+')
      {
          isAdd = true;
          i++;
      }
      else if(str[i]=='-')
      {
          isAdd = false;
          i++;
      }
      else
      {
          j=i;
          while(j<str.length()&&str[j]!='+'&&str[j]!='-')
          {
              j++;
          }
  
          current=stof(str.substr(i,j-i));
  
          if(isAdd)
          {
              ret +=current;
          }
          else
          {
              ret -=current;
          }
          i=j;
      }
  }
 printf("%.2f",ret);
  return 0;
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值