牛客周赛 Round 55

A.模拟

#include<bits/stdc++.h>
using namespace std;
#define int long long

signed main(){
    string s;
    cin>>s;
    map<char,int>mp;
    for(int i=0;i<3;i++){
        mp[s[i]]++;
    }
    int mx=0;
    for(auto [i,j]:mp){
        mx=max(mx,j);
    }
    cout<<3-mx;
    return 0;
}

B.直接暴力累乘会暴,由于相乘后个位数的值只与个位数有关,模拟的时候只保留个位数进行计算即可。

#include<bits/stdc++.h>
using namespace std;
#define int long long

signed main(){
    int n;
    cin>>n;
    int ans=0;
    int sum=1;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        sum*=x;
        sum%=10;
        if(sum==6)ans++;
    }
    cout<<ans;
    return 0;
}

C.最优排列肯定是数组递增的时候,排序后遍历判断一下,如果递增时都不行,那肯定不行

#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[1000010];
signed main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    sort(a+1,a+1+n);
    for(int i=3;i<=n;i++){
        if(a[i]*a[i-1]<=a[i-1]*a[i-2]){
             cout<<"NO";
            return 0;
        }
    }
    cout<<"YES\n";
    for(int i=1;i<=n;i++)cout<<a[i]<<' ';
    return 0;
}

D.建图后跑一遍最短路即可,由于边权为1,我这里用的是bfs,难点在于建图。

#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[1010][1010],book[1010][1010];
vector<pair<int,int>>V[1010][1010];
int fx[4]={0,0,1,-1};
int fy[4]={1,-1,0,0};
signed main(){
    int n;
    cin>>n;
    for(int i=0;i<=n+1;i++){//将边界初始化为墙
        for(int j=0;j<=n+1;j++){
            a[i][j]=1;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++){
        int k=1e9;//这里k表示的是当前遍历的这一行的上一次出现墙的位置,初始化为最大值
        for(int j=0;j<=n+1;j++){
            if(a[i][j]==1){//如果遍历到墙了,就结合上一次出现墙的位置k构造一条边,并更新k的值
                if(j-2>k+1){
                    V[i][j-1].push_back({i,k+1});
                    V[i][k+1].push_back({i,j-1});
                    k=j;
                }else k=j;
            }
        }
    }
    for(int i=1;i<=n;i++){//这个循环同上,只不过是遍历每一列
        int k=1e9;
        for(int j=0;j<=n+1;j++){
            if(a[j][i]==1){
                if(j-2>k+1){
//                     cout<<j-1<<' '<<i<<'-'<<k+1<<' '<<i<<'\n';
                    V[j-1][i].push_back({k+1,i});
                    V[k+1][i].push_back({j-1,i});
                    k=j;
                }else k=j;
            }
        }
    }
//以下则是bfs求最短路
    queue<pair<int,int>>q;
    q.push({1,1});
    book[1][1]=1;
    while(!q.empty()){
        int x=q.front().first;
        int y=q.front().second;
        q.pop();
        if(x==n&&n==y){
            cout<<book[n][n]-1;
            return 0;
        }
        for(int i=0;i<4;i++){//跑上下左右
            int nx=x+fx[i];
            int ny=y+fy[i];
            if(nx>=1&&nx<=n&&ny>=1&&ny<=n&&a[nx][ny]==0&&book[nx][ny]==0){
                book[nx][ny]=book[x][y]+1;
                q.push({nx,ny});
            }
        }
        for(auto [i,j]:V[x][y]){//跑自己构造的边
            if(book[i][j]==0){
                book[i][j]=book[x][y]+1;
                q.push({i,j});
            }
        }
    }
    cout<<-1;
    return 0;
}

E.dp,dp[i][j]表示遍历到第i位时,个位数字为j的方案数。当遍历到j为6时计算一下贡献(也就是当前的dp数组值乘上后面位置的总方案)。

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,a[100010],dp[100010][10],mod=1e9+7;
int ksm(int a,int b){
    int aa=1;
    while(b){
        if(b&1)aa=aa*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return aa;
}
signed main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    dp[0][1]=1;
    int ans=0;
    for(int i=1;i<=n;i++){
        int k=a[i]%10;
        for(int j=0;j<=9;j++){
            dp[i][j]+=dp[i-1][j];
            dp[i][j]%=mod;
            dp[i][j*k%10]+=dp[i-1][j];
            dp[i][j*k%10]%=mod;
            if(j*k%10==6){
                ans+=dp[i-1][j]*ksm(2,n-i)%mod;
                ans%=mod;
            }
        }
        
    }
    cout<<ans;
    return 0;
}

F.计算几何(无板子硬推版QWQ)

#include<bits/stdc++.h>
using namespace std;
vector<pair<double,double>>V;
double dis(double x,double y,double xx,double yy){
    return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy));
}
signed main(){
    double x0,y0,r;
    cin>>x0>>y0>>r;
    int n;
    double d;
    cin>>n>>d;
    for(int i=1;i<=n;i++){
        double x1,y1,x2,y2,s;
        cin>>x1>>y1>>x2>>y2>>s;
        if(x1==x2){
            if(x1==x0+r){
                if((y2-y1)/(y0-y1)<0)continue;
                double tt=fabs((y0-y1)/s);
                V.push_back({tt,tt});
            }else if(x1==x0-r){
                if((y2-y1)/(y0-y1)<0)continue;
                double tt=fabs((y0-y1)/s);
                V.push_back({tt,tt});
            }else if(x1>x0-r&&x1<x0+r){
                double yy1=sqrt(r*r-(x1-x0)*(x1-x0))+y0;
                double yy2=y0-sqrt(r*r-(x1-x0)*(x1-x0));
                if((y2-y1)/(yy1-y1)<0)continue;
                double t1=fabs((yy1-y1)/s);
                double t2=fabs((yy2-y1)/s);
                V.push_back({min(t1,t2),max(t1,t2)});
            }
            continue;
        }
        if(y1==y2){
            if(y1==y0+r){
                if((x2-x1)/(x0-x1)<0)continue;
                double tt=fabs((x0-x1)/s);
                V.push_back({tt,tt});
            }else if(y1==y0-r){
                if((x2-x1)/(x0-x1)<0)continue;
                double tt=fabs((x0-x1)/s);
                V.push_back({tt,tt});
            }else if(y1>y0-r&&y1<y0+r){
                double xx1=sqrt(r*r-(y1-y0)*(y1-y0))+x0;
                double xx2=x0-sqrt(r*r-(y1-y0)*(y1-y0));
                if((x2-x1)/(xx1-x1)<0)continue;
                double t1=fabs((xx1-x1)/s);
                double t2=fabs((xx2-x1)/s);
                V.push_back({min(t1,t2),max(t1,t2)});
            }
            continue;
        }
        double k=(y2-y1)/(x2-x1);
        double b=y1-k*x1;
        double A=(k*k+1),B=(2*k*b-2*k*y0-2*x0),C=(x0*x0+b*b-2*b*y0+y0*y0-r*r);
        double sk=B*B-4*A*C;
        if(sk<0){
            continue;
        }else if(sk==0){
            double xx=-B/(2*A);
            double yy=k*xx+b;
            if((x2-x1)/(xx-x1)<0){
                continue;
            }
            double tt=fabs(dis(xx,yy,x1,y1)/s);
            V.push_back({tt,tt});
        }else {
            double xx1=(-B+sqrt(sk))/(2*A);
            double yy1=k*xx1+b;
            double xx2=(-B-sqrt(sk))/(2*A);
            double yy2=k*xx2+b;
            if((x2-x1)/(xx1-x1)<0){
                continue;
            }
            double t1=fabs(dis(xx1,yy1,x1,y1)/s);
            double t2=fabs(dis(xx2,yy2,x1,y1)/s);
            V.push_back({min(t1,t2),max(t1,t2)});
        }
    }
    sort(V.begin(),V.end());
    double ans=0,cc=0;
    for(int i=0;i<V.size();i++){
        V[i].second+=d;
        ans+=max(V[i].second-max(V[i].first,cc),(double)0);
        cc=max(cc,V[i].second);
    }
    printf("%.10lf",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值