牛客小白月赛13 补题(ACDG)

版权声明:欢迎转载,转载请注明出处,如有错误,还望指出,谢谢 博客地址:https://blog.csdn.net/lanyanzhiji123asd https://blog.csdn.net/lanyanzhiji123asd/article/details/89280079

比赛链接:https://ac.nowcoder.com/acm/contest/549#question

A :

通过已经给的代码,打表找规律,偶数输出-1,奇数输出1

#include<bits/stdc++.h>
using namespace std;
int main() {
    long long n;
    while(~scanf("%lld",&n))
    {
        if(n%2==0)cout<<"-1"<<endl;
        else cout<<"1"<<endl;
    }
     
     
    return 0;
}

C: 概率问题吧,买n张彩票一共有4^n次方方案,然后我们再算出不亏本的方案数

不亏本的方案数有两种方法,一种是直接暴力,数据范围只有30 

第二种方法就是动态规划

dp[ i ][ j ]表示第 i 张彩票得到 j 元的方案数

然后如果n等于0  概率是1

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
#define ll long long
ll dp[35][125];
 
ll gcd(ll a, ll b)
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}
 
void huaj(ll *a, ll *b)
{
    ll temp=gcd((*a),(*b));
    (*a)/=temp;
    (*b)/=temp;
}
 
int main()
{
    std::ios::sync_with_stdio(false);
    int i,j,k,n;
    while(cin>>n)
    {
        if(n==0)
        {
            cout<<"1/1"<<endl;
            continue;
        }
        memset(dp,0,sizeof(dp));
        dp[1][1]=1;
        dp[1][2]=1;
        dp[1][3]=1;
        dp[1][4]=1;
        for(i=2;i<=n;i++)
        {
            for(j=i;j<=4*i;j++)
            {
                for(k=1;k<=4;k++)
                {
                    dp[i][j]+=dp[i-1][j-k];
                }
            }
        }
        ll ans=0,par=1;
        for(i=3*n;i<=4*n;i++)
        {
            ans+=dp[n][i];
        }
//      cout<<ans<<endl;
        if(ans==0)
        {
            cout<<"0/1"<<endl;
        }
        else
        {
            for(i=1;i<=n;i++)
            {
                par*=4;
            }
//          cout<<par<<endl;
            huaj(&ans,&par);
            cout<<ans<<"/"<<par<<endl;
        }
    }
     
     
     
     
     
 
 return 0;
}

D : 前缀或和后缀或

因为或运算与顺序无关

所以我分别用两个数组维护前缀或和后缀或,然后枚举每个数

最后求出最大值

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
#define ll long long
ll mp[5000005],qianz[5000005],houz[5000006];
int main()
{
    std::ios::sync_with_stdio(false);
    int n,i;
    ll ans=-0x3f3f3f3f3f3f3f3f,temp;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>mp[i];
    }
    qianz[0]=0;
    houz[n+1]=0;
    qianz[1]=mp[1];
    houz[n]=mp[n];
    for(i=2;i<=n;i++)
    {
        qianz[i]=qianz[i-1]|mp[i];
    }
    for(i=n-1;i>0;i--)
    {
        houz[i]=houz[i+1]|mp[i];
    }
    for(i=1;i<=n;i++)
    {
        temp=qianz[i-1]|houz[i+1];
        ans=max(ans,temp);
    }
    cout<<ans<<endl;
 
 return 0;
}

G:双向BFS

看了一下别人的代码

用一个队列维护,但是每个入队的点都要标记这个点是从小A走到的还是小B走到的

然后每次判断下如果这个点是小A走到的  但是小B已经走过了,或者这个点是小B走到的,但是小A已经走过了。

用vis数组标记这个点曾经被谁走过

需要注意的是,小B每次是可以走两步的,所以相当于小B走了两步,但是时间花了一秒,小A走了一步,时间花了一秒

所以入队的时候需要注意下

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
#define ll long long
int d[8][2]={0,-1,-1,0,0,1,1,0,-1,-1,-1,1,1,-1,1,1};
struct node
{
    int x,y,id,step;
};
queue<node>q;
int n,m;
char mp[1005][1005];
int vis[1005][1005];
int access(int x,int y)
{
    if(x<=n&&x>0&&y<=m&&y>0&&mp[x][y]=='.'&&!vis[x][y])
        return 1;
    return 0;
}
 
int BFS()
{
    int up,i,j;
    while(!q.empty())
    {
        node v=q.front();
        q.pop();
         
        if(v.id==1)
        {
            up=8;
            for(i=0;i<up;i++)
            {
                int xx=v.x+d[i][0];
                int yy=v.y+d[i][1];
                if(vis[xx][yy]==2)return v.step+1;
                if(access(xx,yy))
                {//cout<<xx<<" "<<yy<<" "<<mp[xx][yy]<<endl;
                    q.push((node){xx,yy,1,v.step+1});
                    vis[xx][yy]=1;
                }
            }
        }
        else
        {
            up=4;
            for(i=0;i<up;i++)
            {
                int xx=v.x+d[i][0];
                int yy=v.y+d[i][1];
                if(vis[xx][yy]==1)return v.step+1;
                if(access(xx,yy))
                {
                    vis[xx][yy]=2;
                    for(j=0;j<up;j++)
                    {
                        int xxx=xx+d[j][0];
                        int yyy=yy+d[j][1];
                        if(vis[xxx][yyy]==1)return v.step+1;//这里需要注意
                        if(access(xxx,yyy))
                        {
                            q.push((node){xxx,yyy,2,v.step+1});//这里需要注意
                            vis[xxx][yyy]=2;
                             
                        }
                    }
                }
            }
        }
    }
    return -1;
}
 
int main()
{
    std::ios::sync_with_stdio(false);
    int i,j;
    while(cin>>n>>m)
    {
        while(!q.empty())
            q.pop();
        memset(vis,0,sizeof(vis));
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                cin>>mp[i][j];
                if(mp[i][j]=='C')
                {
                    q.push((node){i,j,1,0});
                }
                if(mp[i][j]=='D')
                {
                    q.push((node){i,j,2,0});
                }
            }
        }
        int ans=BFS();
        if(ans==-1)
            cout<<"NO"<<endl;
        else
        {
            cout<<"YES"<<endl;
            cout<<ans<<endl;
        }
    }
 
 return 0;
}

猜你喜欢

转载自blog.csdn.net/lanyanzhiji123asd/article/details/89280079