Logo xushuoxin的博客

博客

2023年5月月赛 题解

2023-05-06 22:39:40 By xushuoxin

趁着别人还没出题解,我赶紧连夜写完.

A.Deliv-e-droid 题目链接

简单,语法题,全员AC,直接上代码.

#include<iostream>
using namespace std;
int p,s,c;
int main(){
    cin>>p>>c;
    if(p>c) s=500;
    s+=p*50,s-=c*10;
    cout<<s;
    return 0;
}

B.辣椒 题目链接

简单,又是一道送分题(兼水题,数据太小了,应该设个开long long的坑),上代码

#include<iostream>
using namespace std;
long long n,i,p;
string s;
int main(){
    cin>>n;
    for(i=0;i<n;i++){
        cin>>s;
        if(s=="Poblano")
            p+=1500;
        if(s=="Cayenne")
            p+=40000;
        if(s=="Mirasol")
            p+=6000;
        if(s=="Serrano")
            p+=15500;
        if(s=="Thai")
            p+=75000;
        if(s=="Habanero")
            p+=125000;
    }cout<<p;
    return 0;
}

C.特殊事件 题目链接

依然非常简单,水题,废话不多说,上代码.

(此代码有些繁琐,请自行修改)

#include<bits/stdc++.h>
using namespace std;
int n,i,j,mx,ans[5];string s;
int main(){
    cin>>n;
    for(i=0;i<n;i++){
        cin>>s;
        for(j=0;j<5;mx=max(ans[j],mx),j++)
            if(s[j]=='Y')
                ans[j]++;
    }i=0;
    while(ans[i]!=mx&&i<5) i++;
    cout<<i+1;i++;
    for(;i<5;i++)
        if(ans[i]==mx)
            cout<<","<<i+1;
    return 0;
}

D.三角形 题目链接

看看洛谷题解给的解释吧,字幕君已崩溃

一看这题,两个相邻的黑色三角形,每个黑色的周长都要减去1,因此我们可以一个一个遍历。

那么如何判断相邻?很简单,同行邻列上的黑色三角形相邻,并且奇数列上的黑色三角形也相邻.

所以我们可以按照这个思路写代码.(以上摘抄自洛谷)

上程序!

#include<bits/stdc++.h>
using namespace std;
int n,i,j,a[5][200005],ans;
int main(){
    cin>>n;
    for(i=1;i<=n;i++)
        cin>>a[1][i];
    for(i=1;i<=n;i++)
        cin>>a[2][i];
    for(i=1;i<=2;i++){
        for(j=1;j<=n;j++){
            if(a[i][j]){
                ans+=3;
                if(a[i][j-1])
                    ans-=2;
                if(a[i-1][j]&&j%2)
                    ans-=2;
            }
        }
    }cout<<ans;
    return 0;
}

E.单词查询 题目链接

这题其实和#300很像,但也有很不同的地方(导致我两次都把题审错了,做题目,审题是关键啊)

这明显一个深搜题目,那么,该怎么搜呢——

首先,我们要从网格中找到这个单词的首字母作为起点,

再审审题,起点周边八个方向都搜一圈,看看有没有这个单词第二个字母(这之间有细节,见程序).

如果有,就以此方向为搜索方向,一直搜到底(终止条件和搜索条件见后文).

但再审审题,

另一种方式是单词的字母出现在一个线段上,直到某个字母,然后出现在第二行在这个字母处形成直角的线段。

中途这个方向是可以转一次的(只限90°),那么就要多写一种情况.

该怎么转呢,简单,要么向左转,要么向右转.

例如用0表示左下,1表示左上,2表示右下,3表示右上
     4表示上,5表示下,6表示左,7表示右.
八种方向的转法如下图表示
0->(1,2) 1->(0,3) 2->(0,3) 3->(1,2)
4->(6,7) 5->(6,7) 6->(4,5) 7->(4,5)

这样解决了转的问题,有的同学要问了:

搜索的终止条件和进行条件是什么?

别急,先假设你前面已经搜了l次

进行条件,

就是坐标不出界,下一个要搜的位置上的字母是单词的第l+1个字母.

终止条件

就是搜完了整个单词,即l=单词长度-1.

综上所述,如果还不懂,看看代码吧.(严禁抄袭!)

#include<bits/stdc++.h>
using namespace std;
char s[105],c[105][105];
int n,m,ans,dx[8]={1,1,-1,-1,1,-1,0,0},dy[8]={-1,1,-1,1,0,0,1,-1};
void dfs(int x,int y,int l,int fx,int f){
    if(l==strlen(s)-1){
        ans++;
        return;
    }        
    int ux=x+dx[fx],uy=y+dy[fx];
    if(ux>=0&&ux<n&&uy>=0&&uy<m&&c[ux][uy]==s[l+1])
        dfs(ux,uy,l+1,fx,f);
    if(f==0){
        int tf1,tf2;
        if(fx==0||fx==3)
            tf1=1,tf2=2;
        if(fx==1||fx==2)
            tf1=0,tf2=3;
        if(fx==4||fx==5)
            tf1=6,tf2=7;
        if(fx==6||fx==7)
            tf1=4,tf2=5;
        ux=x+dx[tf1],uy=y+dy[tf1];
        if(ux>=0&&ux<n&&uy>=0&&uy<m&&c[ux][uy]==s[l+1])
            dfs(ux,uy,l+1,tf1,1);
        ux=x+dx[tf2],uy=y+dy[tf2];
        if(ux>=0&&ux<n&&uy>=0&&uy<m&&c[ux][uy]==s[l+1])
            dfs(ux,uy,l+1,tf2,1);                
    }
}
int main(){
    cin>>s>>n>>m;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>c[i][j];
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            if(c[i][j]==s[0]){
                if(strlen(s)==1)
                    ans++;
                else
                    for(int k=0;k<8;k++)
                        if(c[i+dx[k]][j+dy[k]]==s[1])
                            dfs(i+dx[k],j+dy[k],1,k,0);                                
            }
    cout<<ans;
    return 0;
}

评论

乙鸟
写题解都卷成这样了吗? 先置顶,其他几题也补上吧。
Ethan2013
月赛突然变简单了
Ethan2013
@tingting 你笑啥
tingting
@xushuoxin D题是不是偷懒了

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。