牛客小白月赛36

链接:https://ac.nowcoder.com/acm/contest/11213

目录

链接:https://ac.nowcoder.com/acm/contest/11213

         B---最短串

    模板:

    思路:

    AC代码:

C:杨辉三角(数学题,推出公式即可过)

     思路:

    AC代码:

I:四面楚歌

​    思路:

    AC代码:


B---最短串

给定2个由小写字母和问号组成的字符串a与b,问号代表你想要的任何字符。

请你找出最短的字符串s,要求s包含a和b两个字符串,你只需要输出s的长度即可。

模板:

判断B串是否为A串的子串:(可以直接使用)

bool judge(const string &a,const string &b)
{
    int i,j;
    if(a.length()<b.length())return false;
    for(i=0;i<a.length();i++){
        for(j=0;j<b.length();j++){
            if(a[i+j]!=b[j])
                break;   // 字符不相等,退出
        }
        if(j==b.length()) // 达到了b.length,说明字符全部相等
            return true;
    }
    return false;
}

思路:

求最短串长度,先判断以a为后缀时的长度,再判断以b为后缀时的长度,取最短长度即可。有?号的地方直接视为相同即可。

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const int N = 100005;

int cal(string s, string t) {//以t作为后缀
    int res = s.size() + t.size();//res--s,t串总长度,答案的最大值
    for (int i = 0; i < s.size(); i++) {
        int ok = 1;
        for (int j = 0; j < t.size() && i + j < s.size(); j++) {
            if (t[j] == s[i + j] || t[j] == '?' || s[i + j] == '?');
            else {
                ok = 0;
                break;
            }
        }
        if (ok) {//如果t串为s串的子串,从某部分开始全部一样
            res = i + max(t.size(), s.size() - i);//则答案res为s的前缀(s与t不同的部分)
                                                  //加上max(t.size(), s.size() - i)
            break;
        }
    }
    return res;
}
int main() {
    string s, t;
    cin >> s >> t;
    cout << min(cal(s, t), cal(t, s)) << endl;
    return 0;
}

C:杨辉三角(数学题,推出公式即可过)

小F对杨辉三角颇有研究,他把杨辉三角第n行的数提出来,从左到右分别为a[0],a[1],...,a[n−1]。

现在他想知道的值是多少,答案对99824353取模。

 思路:

推出数学公式值为(n-1)*n*2^(n-3);由于n比较大,直接用pow会超时,用快速幂求解此公式。

AC代码:

#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
const int mod = 99824353;
ll f[N];
ll n, m;
ll fp(ll a, ll n)
{
    ll ans = 1;
    ll base = a % mod;
    while (n)
    {
        if (n & 1) ans = ans * base % mod;
        base = base * base % mod;
        n >>= 1;
    }
    return ans % mod;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    while (cin >> n)
    {
        if (n == 1) cout << 0 << endl;
        else if (n == 2) cout << 1 << endl;
        else
        {
            m = n - 1;
            cout << m % mod * (m + 1) % mod * fp(2, m - 2) % mod << endl;
        }
    }
    return 0;
}

I:四面楚歌

在游戏中,因为一次错误的决断,你的士兵被敌方实行围剿。为了挽回人员损失,你不得不开启金手指暂停敌方士兵的移动,从而尽量让自己的士兵能成功突围。

已知地图是一块n×m的区域,每块格子有以下几种类型:

.:表示此处为一块空地。

1:表示此处有敌方士兵,不许通过。因为开启了金手指,所以敌方士兵不会移动。

0:表示此处有我方士兵。

现规定我方士兵只能进行上/下/左/右四个方向的移动,只要某个士兵移动出了地图边界,那么就算该士兵突围成功。请问能有多少士兵成功突围。

 思路:

一道搜索的简单题,DFS,BFS都可以过,对搜索题不太熟,所以好好补了一下这个题,直接看代码。

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,m;
int dx[]={0,0,-1,1};//上下左右 
int dy[]={1,-1,0,0};
char a[1010][1010];
int cnt=0;
int flag[1010][1010];
void dfs(int x,int y)//还没太看懂,看懂了以后回来补
{//如果该点为士兵或者该点已突围出去或者该点的flag==1,满足就返回函数
    if(a[x][y]=='1' || x<0 || x>n+1 || y<0 || y>m+1 || flag[x][y]) //全部不成立就不返回 
    return ;
    //否则定flag=1
    flag[x][y]=1;
    for(int i=0;i<4;i++)
    {//向上下左右四个方向搜索
        dfs(x+dx[i],y+dy[i]);
    }
}
int main()
{
    memset(a,'.',sizeof(a));//全部初始化为空地  .代表空地
    cin>>n>>m;//输入区域大小
    for(int i=1;i<=n;i++)//从1开始 
    {
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
        }
    }
    dfs(0,0);//从起点开始搜索
    for(int i=1;i<=n;i++) //从1开始 
    {
        for(int j=1;j<=m;j++)
        {
            if(a[i][j]=='0' && flag[i][j])
            {
                cnt++;
            }
        }
    }
    cout<<cnt;
}

写在后面的话:第二篇博客,第一篇题解,暑假集训快没有学习方向了,把以前比赛没写好的题补一补,开始加油写题解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值