2023码蹄杯全国职业院校程序设计竞赛省赛(二)题解

A . 捡麦子

#include<bits/stdc++.h> 
using namespace std;
int main( )
{
    // Sn = n * (1 + n) / 2 ;
    int n , ans = 0 ;
    cin >> n ;
    for(int i = 1 ; i <= n ; i ++ ) ans += i * ( i + 1 ) / 2 ;
    cout << ans ; 
    return 0;
}

B. 小码哥玩游戏

个人认为题目中描述“最后统计与该字符相邻的字符数量” 改成 “最后统计与该字符相邻不同的字符数量”或许会易于理解否则会有些许歧义并且题目中解释并没消除该歧义,题目所要统计的是字符本身信息并非是位置信息

例如样例:
2 2 B

0 A

A B

可能会因为歧义最后统计不同位置信息导致输出2 实则是 1 因为与 B相邻的字符中 有且仅有A 虽然它们在不同位置上

而题目中解释的样例:
3 3 A

0 A 0 

A B A

0 A 0 

我可以理解成统计位置信息有  4个(1,1)去重后输出1 也可以理解成只有一个B

除此之外该题主要考察的其实仅仅是统计有效信息+去重 (利用set或者unique函数)

#include <bits/stdc++.h>
using namespace std ;
typedef pair<int,int> PII ;
const int N = 110 ;
char g[N][N] , ch ;
int n , m ;
PII p[4] = {{0,-1},{1,0},{-1,0},{0,1}} ;

int main()
{
    cin >> n >> m >> ch ;
    for(int i = 1 ; i <= n ; i++ ) for(int j = 1 ; j <= m ; j++ ) cin >> g[i][j] ;
    vector<char> ans ;
    for(int i = 1 ; i <= n ; i++ ) 
    {
        for(int j = 1 ; j <= m ; j++ )
        {
            if ( g[i][j] != ch ) continue ;
            for(int k = 0 ; k < 4 ; k++ )
            {
                int nx = i + p[k].first , ny = j + p[k].second ;
                if ( g[nx][ny] >= 'A' && g[nx][ny] <= 'Z' && g[nx][ny] != ch ) 
                {
                    ans.push_back(g[nx][ny]);
                } 
            }
        }
    }
    sort(ans.begin(),ans.end()) ; // 或者放进一个set集合中 输出最后集合中元素个数也可

    cout << unique(ans.begin(),ans.end()) - ans.begin() ; 

    return 0 ;
}

 C . 淘金者

#include<bits/stdc++.h> 
using namespace std;
int main( )
{
    string str , s ;
    cin >> str >> s ;
    if ( str.find(s) == str.npos ) cout << -1 ;
    else cout << str.find(s) + 1 ;
    return 0;
}

 D . 自动浇花机 (模拟)

 关注点可以从俩个方面进行入手

1、路程

2、时间

实际做法逻辑均相同

先考虑 Left 浇当前花所需要的 时间 T 

在 T 时间内 Right 浇到哪一盆花

维护 Left 、 Right 变量即可

#include<bits/stdc++.h> 

using namespace std;

const int N = 1010;
double a[N] , n ;

int main( )
{
    cin >> n ;
    for(int i = 1 ; i <= n ; i++ ) cin >> a[i] ;
    int l = 1 , r = n ;
    while (1) 
    {
        double t = a[l] / 2 ;
        while ( t > 0 ) 
        {
            double x = a[r] ;
            a[r] -= t ;
            t -= x ;
            if ( a[r] <= 0 ) --r ;
        }
        if ( r - l <= 1) break ;
        l ++ ;
    }
    cout << l ;
    return 0;
}

 E . 小码哥的开心数字

#include<bits/stdc++.h> 

using namespace std;

bool cmp(string a,string b)
{
    if ( a.size() != b.size() ) return a.size() > b.size() ;
    for(int i = 0 ; i < a.size() ; i++ ) if ( a[i] != b[i] ) return a[i] > b[i] ;
    return true ; 
}

int main( )
{
    string str , rstr ;
    cin >> str ;
    rstr = str ;
    while ( rstr.size() > 1 && rstr.back() == '0' ) rstr.pop_back() ;
    reverse(rstr.begin(),rstr.end()) ;
    cout << rstr << '\n' ;
    cout << (cmp(rstr,str) ? "True" : "False" ) ;
    return 0;
}

 F . 自驾游

需要注意的是第一做这道题的时候可能会想到一种贪心的想法 :

假设当前位置为 st 最远到 st + Max

如果st + Max < L 那么优先选择在 st + Max 距离内选择 Price_min的加油站进行加油

这一想法并不是最优解

应该采用BFS进行搜索 

#include <bits/stdc++.h>

using namespace std ;
const int inf = 0x3f3f3f3f; 
int N , L , Max , S ;
typedef pair<int,int>PII;
struct node{
    int d , pic , id ;
};

void solve()
{
    PII a[N] ;
    for(int i = 0 ; i < N ; i++ ) cin >> a[i].first >> a[i].second ;
    sort(a,a+N) ;

    queue<node>que;
    que.push({0,S,-1}) ;
    while ( !que.empty() ) 
    {
        node now = que.front() ; que.pop() ;
        if ( now.d + Max >= L ) 
        {
            puts("Yes");
            return ;
        }
        for(int i = now.id + 1 ; i < N ; i++ )
        {
            if(now.d + Max < a[i].first) break ;
            if(now.pic - a[i].second >= 0 ) que.push({a[i].first,now.pic - a[i].second,i}) ; 
        }
    }
    puts("No");
}

int main()
{
    while ( cin >> N >> L >> Max >> S ) solve() ;
    return 0 ;
}

 G . 买月饼

#include<bits/stdc++.h> 

using namespace std;

int main( )
{
    int m , n , i = 1 ; 
    cin >> m >> n ;
    for( ; ; i++ ) if ( m * i % 10 == 0 || (m * i - n) % 10 == 0) break ;
    cout << i ;
    return 0;
} 

H . 未来战争

做法有很多赛时优先选择自己擅长的即可

这边提供的是合并区间的做法

#include <bits/stdc++.h>

using namespace std ;
typedef pair<int,int> PII ;
int n , l , r ;

void merge(std::vector<PII>&a)
{
    std::vector<PII> C;
    l = r = -2e9 ;
    for(auto v : a)
    {
        if ( r < v.first )
        {
            if ( r != -2e9 ) C.push_back({l,r}) ;
            l = v.first , r = v.second ;
        }
        else r = max(r , v.second);
    }
    C.push_back({l,r}) ;
    a = C ;
}

int main()
{
    cin >> n ;
    std::vector<PII>a(n) ;
    for(int i = 0 ; i < n ; i++ ) cin >> a[i].first >> a[i].second ;
    sort(a.begin(),a.end()) ;

    merge(a);

    int ans1 = 0 , ans2 = 0 ;
    n = a.size() ;
    for(int i = 0 ; i < n ; i++ )
    {
        ans1 = max(ans1,a[i].second - a[i].first) ;
        if ( i < n - 1 )ans2 = max(ans2,a[i+1].first - a[i].second) ;
    }
    cout << ans1 << ' ' << ans2 ;
    return 0 ;
}

I . 文章压缩

#include<bits/stdc++.h> 

using namespace std;

int main( )
{
    unordered_map<string,vector<int>> mp;
    vector<string> str; 
    string x ;
    int n ;
    cin >> n ;
    for(int i = 1 ; i <= n ; i++)
    {
        cin >> x ;
        if (mp[x].empty()) str.push_back(x) ;
        mp[x].push_back(i) ;
    }

    for(auto s : str)
    {
        cout << s << '(' ;
        for(int i = 0 ; i < mp[s].size() ; i++ )
        {
            if ( i == 0 ) cout << mp[s][i] ;
            else cout << ',' << mp[s][i] ;
        }
        cout << ')' ;
    }
    return 0;
}

J . 魔法水晶球

数据很小 判断质数 用试除法即可

#include<bits/stdc++.h> 

using namespace std;

bool is_prime(int x)
{
    if ( x < 2 ) return false ;
    for(int i = 2 ; i <= x / i ; i++ ) if ( x % i == 0 ) return false ;
    return true ;
}

int main( )
{
    int n ; 
    cin >> n ; 
    if ( is_prime(n) ) cout << 'P' ;
    else if ( n & 1 ) cout << 'O' ;
    else cout << 'E' ;
    return 0;
}

K . 手机测试(模拟)

#include<bits/stdc++.h> 

using namespace std;
const int N = 110 ;
int a , m , n , k , t1 , t2 , l[N] , r[N] , ans ;

int main( )
{
    cin >> a >> m >> n >> k >> t1 >> t2 ;
    for(int i = 1 ; i <= a ; i++ ) cin >> l[i] >> r[i] ;

    for(int i = 1 ; ; i++ ) 
    {
        ans += m * (r[i] - l[i]) ;
        if ( i == a ) break ;
        int t = l[i + 1] - r[i] ;
        ans += min(t1 , t) * m ;
        t -= t1 ;
        if ( t <= 0 ) continue ;
        ans += min(t2 , t) * n ;
        t -= t2 ;
        if ( t <= 0 ) continue ;
        ans += t * k ;
    }
    
    cout << ans ; 
    return 0;
}

L . 银河贸易市场

该题做法也很多 单调队列 、 线段树 等

这边提供 二维ST表做法 赛时选择更擅长的方式去做即可

时间复杂度O(N^2logN)

#include <bits/stdc++.h>

using namespace std ;
const int N = 1010;
int a[N][N] , n , m , len , Log[N] ;
int st[3][N][N][15] ; // 0 最小 1 最大
inline int max(int a,int b,int c,int d) {
    int mx = a ; if ( mx < b ) mx = b ; if ( mx < c ) mx = c ; if ( mx < d ) mx = d ;
    return mx ;
}
inline int min(int a,int b,int c,int d) {
    int mn = a ; if ( mn > b ) mn = b ; if ( mn > c ) mn = c ; if ( mn > d ) mn = d ;
    return mn ;
}
void Init(){
    for(int i = 2 ; i < N ; i++ ) Log[i] = Log[i>>1] + 1 ;
    for(int i = 1 ; i <= n ; i++ ) for(int j = 1 ; j <= m ; j++ ) st[0][i][j][0] = st[1][i][j][0] = a[i][j] ;
    for(int k = 1 ; k < 15 ; k++ )
        for(int i = 1; i + (1 << k) - 1 <= n ;i ++)
            for(int j = 1 ;j + (1 << k) - 1 <= m ; j++){
                int t1 = st[0][i][j][k-1] , t2 = st[0][i+(1<<(k-1))][j][k-1] , t3 = st[0][i][j+(1<<(k-1))][k-1] , t4 = st[0][i+(1<<(k-1))][j+(1<<(k-1))][k-1] ;
                st[0][i][j][k] = min(t1,t2,t3,t4) ;
                t1 = st[1][i][j][k-1] , t2 = st[1][i+(1<<(k-1))][j][k-1] , t3 = st[1][i][j+(1<<(k-1))][k-1] , t4 = st[1][i+(1<<(k-1))][j+(1<<(k-1))][k-1] ;
                st[1][i][j][k] = max(t1,t2,t3,t4) ;
            }
}
int query(int r,int c){
    int k = Log[len] ;
    int t1 = st[0][r][c][k] , t2 = st[0][r+len-(1<<k)][c][k] , t3 = st[0][r][c+len-(1<<k)][k] , t4 = st[0][r+len-(1<<k)][c+len-(1<<k)][k];
    int mn = min(t1,t2,t3,t4);
    t1 = st[1][r][c][k] , t2 = st[1][r+len-(1<<k)][c][k] , t3 = st[1][r][c+len-(1<<k)][k] , t4 = st[1][r+len-(1<<k)][c+len-(1<<k)][k];
    int mx = max(t1,t2,t3,t4);
    return mx - mn ;
}

int main()
{
    cin >> n >> m >> len ;
    for(int i = 1 ; i <= n ;i++) for(int j =1 ; j <= m ;j++ )cin >> a[i][j] ;
    Init();
    int ans = 0x3f3f3f3f;
    for(int i = 1 ; i + len - 1 <= n ; i++ )
        for(int j = 1 ; j + len - 1 <= m ; j++ ){
            int tmp = query(i,j);
            ans = ans < tmp ? ans : tmp ;
        }
    cout << ans ;
    return 0 ; 
}

 M . 双人成行(模拟)

#include<bits/stdc++.h> 

using namespace std;

const int N = 1e4 + 10 ;
bitset<N>st;

int main( )
{
    int n ;
    cin >> n ;
    for(int i = 1 ; i <= 2 ; i++ )
    {
        int x , y ; 
        cin >> x ;
        while ( x -- ) 
        {
            cin >> y ;
            st[y] = 1 ;
        }
    }

    cout << (st.count() == n ? "It Takes Two." : "Maybe Next Time.") ;
    return 0;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chenRenning

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值