这周三就要去机试,我赶紧做了一下往年的题目,牛客上只找到一篇,所以赶紧写了一下,一看,看来明天是凉凉了,下面开始三题的注解,主要的思路见注释。
(在看到精炼完美的代码时,发现他们经常会用到vector,string,algorithm库,所以想在题解完毕之后对那些经常用到的简单地总结一下)

第一题

#include <iostream>
#include <stdio.h>
#include <vector>

using namespace std;

int main()
{
    int N = 0, M = 0;//第一个为人数,第二个更新的次数
    int score[30001] = {0};//题目讲明不超过30000
    int tempMaxScore = 0;//最高分
    int nIndex = 0;//下标
    int A = 0,B = 0;//修改内容
    char chMode = 0;//修改符
    //除n,m外的变量,都可以放入while循环里面
    while (cin >> N >> M)//多组数据测试,故用while循环
    {
        nIndex = 1;
        while(N--)
        {
            cin >> score[nIndex];//将成绩全部存到score数组
            nIndex++;
        }

        while(M--)
        {
            cin >> chMode >> A >> B;
            if(chMode == 'Q')//表示查询
            {

                int start = (A < B) ? A:B;
                int end = (A < B) ? B:A;//这两步保证了a<b
                tempMaxScore = 0;//相当于哨兵,依次比较
                for(nIndex = start; nIndex <= end; nIndex++)//找出a到b之间的最大值
                {
                    if(score[nIndex] > tempMaxScore )
                    {
                        tempMaxScore = score[nIndex];
                    }

                }
                cout << tempMaxScore << endl;
            }
            else if(chMode == 'U')//更新操作
            {
                score[A] = B;
            }
        }
    }



    return 0;
}

其实上述代码有点麻烦,而且可读性差,我看见另一位大佬写的代码简洁有效,下面给出一个较好的答案:

#include<algorithm>//算法库(之后会有小小的总结)
#include<vector>//容器库
#include<iostream>
using namespace std;

int main()
{
    int N,M;
    while(cin>>N>>M)
  {
        vector<int> stu(N);//首先创建int容器保存分数
        int a,b;char c;//修改符和修改值
        for(int i=0;i<N;++i)
        {
        cin>>stu[i];//把成绩保存到容里
        }
        for(int j=0;j<M;++j)
       {
            cin>>c>>a>>b;
            if(c=='Q')
            {
                if(a>b)swap(a,b);//属于算法库里的函数,交换函数
                cout<<*max_element(stu.begin()+a-1,stu.begin()+b)<<endl;  
//属于算法库里函数,返回的时迭代器,所以加上取内容符号,另外范围是左开右闭,即[a,b),所以一个是a-1,一个是b.(注意下标从0开始)                 
            }   
            if(c=='U')
            {
              stu[a-1]=b;
            }        
        }
    }
    return 0;
}

一目了然啊,代码赏心悦目,直接用swap()函数交换,用max_element()函数返回容器里最大值的迭代器,思路清晰。
第二题

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

bool compare(pair<string, int> a, pair<string, int> b)
    //将输入分为路径和后面的数字(行数),这个函数表示返回数字大的;
    //注意到,pair 中有两个值 一个是first另一个是second
         {
             return a.second > b.second;
         }
int main()
{
    string input, file;//一个是输入,一个是将截断输入获取文件名
    vector<pair<string, int>> errors;//一个基本类型为pair的容器
    while (getline(cin, input))//多次输入用while
    {
        if (input.size() == 0)
        {
             break;
        }

        unsigned int f = input.rfind('\\');//从右往左寻找\,注意到多一个\表示转义
        file = input.substr(f + 1);//于是输入从右往左第一个\后面的就是文件名
        errors.push_back(make_pair(file, 1));//将其放入容器并编号1
        for (int i = 0; i<(errors.size() - 1); i++)
        {
            if (errors[i].first == file)//检查是否重名,若重名,将数目加一并删除一个相同的
            {
                errors[i].second++;
                errors.pop_back();
                break;
            }
        }
    }
    stable_sort(errors.begin(), errors.end(), compare);//按second大小排序,并且stable_sort是稳定排序
    int idx = 0;
    while (idx<8 && idx<errors.size())//最多8个
    {
        string check = errors[idx].first;
        int t = check.find(' ');//空格前面的即文件名
        if (t>16)//文件名称不超过16
        {
            errors[idx].first.erase(0, t - 16);
        }
        cout << errors[idx].first << ' ' << errors[idx].second << endl;
        idx++;
    }
}

该代码中仍有很多库函数,使代码变得简洁,思路清晰。
第三题

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
    string s;
    while(getline(cin,s))//多个测试用例,用while循环
    {
        if(s.find("joker JOKER")!=-1)//find()函数,有大小王,则大小王最大。find()函数找不到则返回-1,否则返回指向该元素的迭代器
        {
            cout<<"joker JOKER"<<endl;
        }
        else
        {
            int temp=s.find('-');//找到分割符,使其分为两部分
            string s1=s.substr(0,temp);//第一部分
            string s2=s.substr(temp+1);//第二部分
            int c1=count(s1.begin(),s1.end(),' ');//count()函数,计算[]之间空格个数,这就间接知道了字符个数了
            int c2=count(s2.begin(),s2.end(),' ');//第二部分的字符个数
            string a1=s1.substr(0,s1.find(' '));//第一部分第一个数
            string a2=s2.substr(0,s2.find(' '));
            string str="345678910JQKA2jokerJOKER";
            if(c1==c2)
            {
                if(str.find(a1)>str.find(a2))//长度一样,只需比较第一个数即可,无论是对子,炸弹,顺子
                {
                    cout<<s1<<endl;
                }
                else
                {
                    cout<<s2<<endl;
                }
            }
            else if(c1==3)//三张牌 只能跟同类比较或炸弹,长度不一样,跟炸弹比,很显然比炸弹小
            {
                cout<<s1<<endl;
            }
            else if(c2==3)//同理
            {
                cout<<s2<<endl;
            }
            else//只能同类型比较(或炸弹),其他情况讨论可知都是错误的
            {
                cout<<"ERROR"<<endl;
            }
        }
    }
}

暂且这样,将在下一篇博客简单总结 “容器,迭代器,算法”,再见,朋友们!
图片说明