这周三就要去机试,我赶紧做了一下往年的题目,牛客上只找到一篇,所以赶紧写了一下,一看,看来明天是凉凉了,下面开始三题的注解,主要的思路见注释。
(在看到精炼完美的代码时,发现他们经常会用到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;
}
}
}
}
暂且这样,将在下一篇博客简单总结 “容器,迭代器,算法”,再见,朋友们!

京公网安备 11010502036488号