2023天梯赛题解目录
L1-1 最好的文档
输出一句话
#include<bits/stdc++.h>
using namespace std;
int main()
{
cout<<"Good code is its own best documentation.";
return 0;
}
L1-2 什么是机器学习
直接依题意输出即可
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
cout<<a+b-16<<endl;
cout<<a+b-3<<endl;
cout<<a+b-1<<endl;
cout<<a+b<<endl;
return 0;
}
L1-3 程序员买包子
依题意输出即可
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m,k;
string x;
cin>>n>>x>>m>>k;
if(k==n)
cout<<"mei you mai "<<x<<" de"<<endl;
else if(k==m)
cout<<"kan dao le mai "<<x<<" de"<<endl;
else
cout<<"wang le zhao mai "<<x<<" de"<<endl;
return 0;
}
L1-4 进化论
依题意输出即可
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b,c;
int n;
cin>>n;
while(n--){
cin>>a>>b>>c;
if(a*b==c)
cout<<"Lv Yan"<<endl;
else if(a+b==c)
cout<<"Tu Dou"<<endl;
else
cout<<"zhe du shi sha ya!"<<endl;
}
return 0;
}
L1-5 猜帽子游戏
分类讨论,输的情况是全体弃权或有一人答错,赢的情况是有人答对且无人答错。设置两个变量判断答对和答错情况。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
int a[101];
for(int i=0;i<n;i++)
cin>>a[i];
int k;
cin>>k;
while(k--){
int bj=0,bj1=0;
for(int i=0;i<n;i++){
int x;
cin>>x;
if(x==a[i]) bj=1;
else if(x!=a[i]&&x!=0) bj1=1;
}
if(bj1||!bj){
cout<<"Ai Ya"<<endl;
}else if(bj&&!bj1){
cout<<"Da Jiang!!!"<<endl;
}
}
return 0;
}
L1-6 剪切粘贴
灵活使用substr函数即可,需要注意的是,s.substr(a,b),a是所截取的子串在原始字符串的起始位置,而b则是截取长度,不是子串的终止位置!
还有一点是题中给出的粘贴位置s1和s2一定是连接在一起的字符串,所以这里需要做一个判断,任何只有s1或s2或s1s2分隔的原字符串都只能将剪切的子串粘贴在末尾。很妙的做法就是直接将s1和s2合并成一个字符串进行查找判断。
(这题比赛的时候卡了很久…真的很简单啊啊,忘记删掉我用来检查的输出所以答案错误。。真的不甘心)
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
string s;
cin>>s;
cin>>n;
for(int i=0;i<n;i++){
int a,b;
string s1,s2;
cin>>a>>b>>s1>>s2;
string str=s.substr(a-1,b-a+1);
s=s.substr(0,a-1)+s.substr(b,-1);
// cout<<"s:"<<s<<endl;
s2=s1+s2;
string s3;//防止对s前半部分截取操作影响后面的操作,所以设一个空字符串
if(s.find(s2)!=string::npos){
int pos=s.find(s2);
s3=s.substr(0,pos+s1.length())+str+s.substr(pos+s1.length(),-1);
s=s3;
}else{
s+=str;
}
}
cout<<s;
return 0;
}
L1-7 分寝室
这题我的思路是,先将可能的寝室人数写入一个数组(因为要求相同性别的寝室人数都要一致,所以总人数/寝室人数一定是整除的),再遍历某个性别可能的寝室人数数组,二层遍历另一个性别可能的寝室人数,判断是否满足刚好分完寝室的要求即可,在二层遍历中用一个minn标记不同性别寝室人数之差,记录最小的,最终遍历结束答案也就出来了。
注意有可能没有答案,所以用来记录最小寝室人数之差的字符也可以作为有没有答案的标记。
记得最后是输出男女寝室数而非寝室人数!
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b,c;
int aa[1001],bb[1001];//存一间寝室可能的人数
cin>>a>>b>>c;
int cnt1=0,cnt2=0;
for(int i=2;i<=a;i++){
if(a%i==0){
aa[cnt1++]=i;
}
}
for(int i=2;i<=b;i++){
if(b%i==0){
bb[cnt2++]=i;
}
}
int minn=1000000;
int ans1=0,ans2=0;
for(int i=0;i<cnt1;i++){//对可能的女生房间人数遍历
if(a/aa[i]<=c){
for(int j=0;j<cnt2;j++){
if(a/aa[i]+b/bb[j]==c){//刚好分完
if(minn>abs(aa[i]-bb[j])){
ans1=aa[i];
ans2=bb[j];
minn=abs(aa[i]-bb[j]);
}
}
}
}
}
if(!ans1&&!ans2){
cout<<"No Solution"<<endl;
}else{
cout<<a/ans1<<" "<<b/ans2<<endl;
}
return 0;
}
L1-8 谁管谁叫爹
这题我的思路是,将题中初始输入的数字改成用字符串输入,这样可以方便我们累加其每位之和,然后再将字符串转换成数字,具体如代码所示。之后就可以按照题意进行比较判断了。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
string a,b;
while(n--){
cin>>a>>b;
int cnt1=0,cnt2=0;
for(int i=0;i<a.length();i++){
cnt1+=(int)(a[i]-'0');
}
for(int i=0;i<b.length();i++){
cnt2+=(int)(b[i]-'0');
}
int x=0,y=0;//a,b的int形态
int p=1;
for(int i=a.length()-1;i>=0;i--){
x+=(int)(a[i]-'0')*p;
p*=10;
}
p=1;//变成初始状态
for(int i=b.length()-1;i>=0;i--){
y+=(int)(b[i]-'0')*p;
p*=10;
}
if(x%cnt2==0&&y%cnt1!=0){
cout<<"A"<<endl;
}else if(y%cnt1==0&&x%cnt2!=0){
cout<<"B"<<endl;
}else{
if(x>y){
cout<<"A"<<endl;
}else{
cout<<"B"<<endl;
}
}
}
return 0;
}
L2-1 堆宝塔
栈的模拟题,按题意步骤操作就行。在存放堆好的宝塔时可以用vector二维数组存放,便于之后计算宝塔个数。
注意,可能A柱或B柱最后上面都是空的,所以要注意宝塔个数的判断。
(就是这样一道如此简单的题,我0分,结束才发现是因为遍历栈的操作写错了,我看了n遍思路都没发现问题,真的特别可惜,简单的送分题55555)
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
stack<int> s1;
stack<int> s2;
cin>>n;
int a[1001];
vector<int>G[1000];
for(int i=0;i<n;i++){
cin>>a[i];
}
int cnt=0;
s1.push(a[0]);
for(int i=1;i<n;i++){
if(s1.top()>a[i]){
s1.push(a[i]);
}else{
if(s2.empty()||s2.top()<a[i]){
s2.push(a[i]);
}else{
while(!s1.empty()){
int x=s1.top();
G[cnt].push_back(x);
s1.pop();
}
cnt++;
while(!s2.empty()){
if(s2.top()>a[i]){
s1.push(s2.top());
s2.pop();
}else{
break;
}
}
s1.push(a[i]);
}
}
}
int ans=cnt;
int a1=s1.size();
int a2=s2.size();
if(a1) ans+=1;
if(a2) ans+=1;
int maxx=max(a1,a2);
for(int i=0;i<cnt;i++){
if(G[i].size()>maxx)
maxx=G[i].size();
}
cout<<ans<<" "<<maxx;
return 0;
}
L2-2 天梯赛的赛场安排
这题我只拿了21分,还差4分有无大佬帮看看qaq。
我的思路是:用一个结构体存学校姓名、未被安排进考场的人数和需要联系的监考老师数(即这个学校学生被安排的考场数),再用一个vector数组存放当前已有的每个考场的空余容量。边输入边判断该学校人数,如果大于考场容量,则直接除以考场容量得到考场数,再将剩下的未分配的学生存回结构体的num中;如果小于考场容量,则先判断当前已有考场的剩余容量够不够,不够则新开,逻辑和题意是一样的。
经过这一轮处理,接下来只需要遍历我们的结构体,对还有未被安排进考场的学生进行处理,逻辑和上一轮是一样的,再输出答案即可。
需要注意:每次vector数组发生变化都必须对其进行排序,因为题目要求优先安排容量最小的考场;遍历剩余考场时要设置标记变量,因为可能不存在合适的考场,就需要重新开一个。
#include<bits/stdc++.h>
using namespace std;
struct ex{
string name;
int num;
int cnt=0;//联系的老师
}sc[5001];
int main()
{
int n,c;
cin>>n>>c;
vector<int> p;
int ans=0;//考场数
for(int i=0;i<n;i++){
cin>>sc[i].name>>sc[i].num;
if(sc[i].num>=c){
int x=sc[i].num/c;
sc[i].cnt+=x;
sc[i].num=sc[i].num-c*x;
ans+=x;
}else{
int bj=0;
if(!p.size()){
for(int j=0;j<p.size();j++){
if(p[j]>=sc[i].num){
sc[i].cnt++;
p[j]-=sc[i].num;
sc[i].num=0;
sort(p.begin(),p.end());
bj=1;
break;
}
}
}
if(!bj){
p.push_back(c-sc[i].num);
ans++;
sc[i].num=0;
sc[i].cnt++;
sort(p.begin(),p.end());
}
}
}
for(int i=0;i<n;i++){
if(sc[i].num==0){
continue;
}else{
int bj=0;
for(int j=0;j<p.size();j++){
if(p[j]>=sc[i].num){
sc[i].cnt++;
p[j]-=sc[i].num;
sc[i].num=0;
sort(p.begin(),p.end());
bj=1;
break;
}
}
if(!bj){
p.push_back(c-sc[i].num);
ans++;
sc[i].num=0;
sc[i].cnt++;
sort(p.begin(),p.end());
}
}
}
for(int i=0;i<n;i++){
cout<<sc[i].name<<" "<<sc[i].cnt<<endl;
}
cout<<ans;
return 0;
}
L2-3 锦标赛
L2-4 寻宝图
#include<bits/stdc++.h>
using namespace std;
const int N=35000;
vector<string > a;
int n,m;
int cnt=0,ans=0;
bool bj=0;
void dfs(int i,int j){
if(a[i][j]>'1') bj=1;
a[i][j]='0';
if(i>0&&a[i-1][j]!='0')
dfs(i-1,j);
if(i<n-1&&a[i+1][j]!='0')
dfs(i+1,j);
if(j>0&&a[i][j-1]!='0')
dfs(i,j-1);
if(j<m-1&&a[i][j+1]!='0')
dfs(i,j+1);
return ;
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
string x;
cin>>x;
a.push_back(x);
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(a[i][j]!='0'){
cnt++;
dfs(i,j);
if(bj==1){
ans++;
bj=0;
}
}
}
}
cout<<cnt<<" "<<ans<<endl;
return 0;
}