2021年第三届计算机能力挑战赛C++决赛试题
前言
下面代码都是自己写的,因为做题系统不能立马给出代码的通过情况。所以可能存在有些条件考虑不全面的问题。若发现代码有误,欢迎在评论区指出哦~
题目
1:
分析:这道题,判断回文就OK
#include <iostream>
#include <iomanip>
#include <cstring>
#include <algorithm>
#include <sstream>
using namespace std;
bool judge(int value){
stringstream ss;
ss<<value;
string str;
ss>>str;
int len=str.length();
string s="";
for (int i=len-1;i>=0;i--){
s+=str[i];
}
if (s==str){
return true;
}
return false;
}
int main()
{
int l,r,k;
cin>>l>>r>>k;
int ans=0;
for (int i=l;i<=r;i++){
if (judge(i)&&i%k==3){
ans++;
}
}
cout<<ans;
}
2:
分析:这道题我用的是全部枚举,总共16种情况,这个方法有点笨~ 做到一半突然发现可以用数组来存运算符,依次遍历这些运算符,可能代码要简洁点。
#include <iostream>
#include <iomanip>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <set>
using namespace std;
int main()
{
// a+b?c?d
int a,b,c,d;
cin>>a>>b>>c>>d;
set<int>s;
int value1=a+b+c-d;
int value2=a+b+c*d;
int value3=a+b+c/d;
int value4=a+b-c+d;
int value5=a+b-c*d;
int value6=a+b-c/d;
int value7=a+b*c+d;
int value8=a+b*c-d;
int value9=a+b*c/d;
int value10=a+b/c+d;
int value11=a+b/c-d;
int value12=a+b/c*d;
int value13=a+b+c+d;
int value14=a+b-c-d;
int value15=a+b*c*d;
int value16=a+b/c/d;
s.insert(value1);
s.insert(value2);
s.insert(value3);
s.insert(value4);
s.insert(value5);
s.insert(value6);
s.insert(value7);
s.insert(value8);
s.insert(value9);
s.insert(value10);
s.insert(value11);
s.insert(value12);
s.insert(value13);
s.insert(value14);
s.insert(value15);
s.insert(value16);
cout<<s.size();
}
3:
分析:这个题的话,用优先队列就好了。优先队列存的是相邻柱子的距离,每次找出最大的距离,若要添加柱子,只能加在最大距离之间,而且最好是在最大距离的中间。还要注意距离包括从0点,也就是原点到第一颗柱子的距离和最后一颗柱子到终点的距离。
#include <iostream>
#include <iomanip>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <set>
#include <queue>
using namespace std;
int main()
{
priority_queue<int>q;
int len,n,m;
cin>>len>>n>>m;
int a[n+2];
a[0]=0;a[n+1]=len;
for (int i=1;i<=n;i++){
cin>>a[i];
}
for (int i=1;i<n+2;i++){
q.push(a[i]-a[i-1]);
}
for (int i=0;i<m;i++){
int value=q.top();
q.pop();
q.push(value/2);
q.push(value-value/2);
}
cout<<q.top();
}
4:
分析:这个题就是用struct或者class,题目没明确告诉前N个是客户端,但我把它默认成前N个是客户端了,emm
大概思路是这样:用map来匹配info和str,用map的好处是快速找到str对应的客户端,比较方便。
比较坑的是代码段的a[i].tt=i;必须要在mmp[a[i].str]=a[i];之前,否则后面int t=temp.tt;这句话得到的t不是下标,多仔细点就OK。
#include <iostream>
#include <iomanip>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <set>
#include <cmath>
#include <map>
using namespace std;
struct info{
string str;
char ch;
string number;
int x,y;
double dis;
int tt;//第几个
string match;//匹配的
};
bool cmp(info a1,info a2){//递增
return a1.number<a2.number;
}
int main()
{
int n;
cin>>n;
map<string,info>mmp;
info a[n];
for (int i=0;i<2*n;i++){
if (i<n){
cin>>a[i].str>>a[i].ch>>a[i].number>>a[i].x>>a[i].y;
a[i].tt=i;
mmp[a[i].str]=a[i];
}
else{
string str,number;
char ch;
int x,y;
cin>>str>>ch>>number>>x>>y;
info temp=mmp[str];
double distance=sqrt((temp.x-x)*(temp.x-x)+
(temp.y-y)*(temp.y-y));
temp.dis=distance;
temp.match=number;
int t=temp.tt;
a[t]=temp;
}
}
sort(a,a+n,cmp);
cout<<setiosflags(ios::fixed)<<setprecision(2);
for (int i=0;i<n;i++){
cout<<a[i].number<<" "<<a[i].match<<" "<<a[i].dis<<endl;
}
return 0;
}
5:
分析:这个题把设置陷阱的位置按递减排个序就Ok,每次都取离起点距离最大的陷阱,可以保证得到的陷阱数最少
#include <iostream>
#include <iomanip>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <set>
#include <cmath>
#include <map>
using namespace std;
bool cmp(int a,int b){
return a>b;
}
int main()
{
int n,l,v;
cin>>n>>l>>v;
int a[n];
for (int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n,cmp);//递减
//cout<<a[0];
int q;
cin>>q;
for (int i=0;i<q;i++){
int j;
cin>>j;
if (j<l*1.0/v){
cout<<"0"<<endl;
}
else{
int cnt=0;
int len=l;
bool flag=false;
for (int k=0;k<n;k++){
len+=a[k];
cnt++;
double time=len*1.0/v;
if (j<time){
flag=true;
cout<<cnt<<endl;
break;
}
}
if (!flag){
cout<<"-1"<<endl;
}
}
}
return 0;
}
最后
本人菜鸡一枚,可能有很多错误或者没考虑到的地方,若有大佬发现后,请不吝赐教,欢迎在评论区指出~~