牛客寒假训练营一

本文提供了几道编程竞赛题目,涉及C++实现的模拟游戏、贪心算法解决文章分配问题、数学几何计算以及字符串处理。题目涵盖了不同的解题思路,如判断比赛胜负、计算文章分配数量、处理几何图形交叠问题以及找出坏字符串的数量。
摘要由CSDN通过智能技术生成

A题

思路:感觉跟模拟差不多,按照题意来就行,每踢一球之后进行判断,停止比赛的条件为:a的进球数量大于b的进球数量+b的剩余场数,反过来b也可以大于a的。出现了这种情况就直接返回,否则跑到最后输出-1即可,表示没有输出胜负。

#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<string.h>
#include<queue>
#include<vector>
using namespace std;
const int N=1e5+5;  
typedef long long ll;

void solve()
{
    string s;
    cin>>s;
    s=" "+s;
    int i;
    int a=0;
    int b=0;
    int at=5;
    int bt=5;
    for(i=1;i<=10;i++){
        if(i%2!=0){
            if(s[i]=='1'){
                a++;
            }
            at--;
        }
        else{
            if(s[i]=='1'){
                b++;
            }
            bt--;
        }
        if(a>b+bt||b>a+at){
            cout<<i<<endl;
            return;
        }
    }
    cout<<-1<<endl;
}

int main()
{   
    int t;
    t=1;
    cin>>t;
    while(t--){
        solve();
    }
    system("pause");
    return 0;
}


C题

思路:贪心的思想吧,就是每个教授分一份文章,当文章的引用量大于0的时候ans就++,最后输出ans即可。

#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<string.h>
#include<queue>
#include<vector>
using namespace std;
const int N=1e5+5;  
typedef long long ll;
ll a[N];

void solve()
{
    int n;
    int i;
    cin>>n;
    int ans=0;
    for(i=0;i<n;i++){
        cin>>a[i];
        if(a[i]>0){
            ans++;
        }
    }
    cout<<ans<<endl;
}

int main()
{   
    int t;
    t=1;
    cin>>t;
    while(t--){
        solve();
    }
    system("pause");
    return 0;
}


 D题

 

思路:分类讨论点位于1,2,3,4四个区域的情况。

#include<iostream>
#include<map>
#include<algorithm>
#include<set>
#include<string>
#include<string.h>
#include<math.h>
#include<vector>
#include<queue>
#include<unordered_map>
typedef long long ll;
const int N=2e5+5;
ll mod=1e9+7;
using namespace std;
typedef pair<int,int> p;


void solve()
{
    int x,y,xp,yp;
    cin>>x>>y>>xp>>yp;

    if(xp<=x&&yp<=y){
        double ans =1.0 * max(xp, x - xp) * max(yp, y -yp) / (x * y);
        printf("%.9lf\n",ans);
    }
    else if(xp<x&&yp>y){
        double s1=(xp*y)*1.0/((x*y)+xp*(yp-y));
        double s2=(x-xp)*y*1.0/((x*y)+(x-xp)*(yp-y));
        double ans=max(s1,s2);
        printf("%.9lf\n",ans);
    }
    else if(xp>=x&&yp>=y){
        double s1=x*y;
        double s2=xp*yp;
        double ans=s1*1.0/s2;
        printf("%.9lf\n",ans);
    }
    else if(xp>x&&yp<y){
        double s1=(x*yp*1.0)/((x*y)+(xp-x)*yp);
        double s2=(y-yp)*x*1.0/((x*y)+(xp-x)*(y-yp));
        double ans=max(s1,s2);
        printf("%.9lf\n",ans);
    }
}
    


int main()
{    
    int t;
    cin>>t;
    while (t--)
    {
        solve();
    }
    system("pause");
    return 0;

}

 G题

思路:首先对于这题,我们验证一会可以发现,当某个数经过少量的操作次数后,可以得到f(x)=x,于是我们可以用set去记录,题目中k最大是1e9,但是上文中也曾提到,我们根本用不到这么多次操作,经过计算可以发现,最大的操作是20,而且数组长度最大是1e5,所以最大的计算量为1e7,不用怕超时,然后对于求和这个操作,我们可以先减去这个数,然后对x进行f(x)的操作,最后加上x。最后如果x的值不变了,就将其从set中除去。

#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<string.h>
#include<queue>
#include<vector>
#include<set>
using namespace std;
const int N=1e5+5;  
typedef long long ll;
ll a[N];

int f(int n)
{
    return round(10*sqrt(n));
}
void solve()
{
    int n,m;
    cin>>n>>m;
    int i;
    set<int> z;
    ll ans=0;
    for(i=1;i<=n;i++){
        cin>>a[i];
        if(a[i]!=f(a[i])){
            z.insert(i);
        }
        ans+=a[i];
    }
    z.insert(n+1);
    for(i=0;i<m;i++){
        int op;
        cin>>op;
        if(op==1){
            int l,r,k;
            cin>>l>>r>>k;
            while(1){
                int now=*(z.lower_bound(l));
                if(now>r){
                    break;
                }
                for(int j=1;j<=min(20,k);j++){
                    ans-=a[now];
                    a[now]=f(a[now]);
                    ans+=a[now];
                }
                if(a[now]==f(a[now])){
                    z.erase(now);
                }
                l=now+1;
            }
        }
        else{
            cout<<ans<<endl;
        }
    }


}

int main()
{   
    int t;
    t=1;
   // cin>>t;
    while(t--){
        solve();
    }
    system("pause");
    return 0;
}


H题

题目太长就不截图了。

思路:题目标题纯诈骗,这题跟dfs没有任何关系,因为我们知道一块完整的碎片(没有凸凹)的价值是10,现在给出n*n-1个拼图碎片的数据,想知道最后一块的价值,所以对于一块碎片,当其突出的时候,也就代表着,最终的那一块会少一部分,反之,凹进去的时候,最终的那一块会多一部分。

#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<string.h>
#include<queue>
#include<vector>
#include<set>
using namespace std;
const int N=1e5+5;  
typedef long long ll;

void solve()
{
    int n;
    cin>>n;
    n*=n;
    int i;
    ll ans=10;
    for(i=0;i<n-1;i++){
        char a[4];
        for(int j=0;j<4;j++){
            cin>>a[j];
            if(a[j]=='1'){
                ans++;
            }
            if(a[j]=='2'){
                ans--;
            }
        }
    }
    cout<<ans<<endl;
}

int main()
{   
    int t;
    t=1;
    cin>>t;
    while(t--){
        solve();
    }
    system("pause");
    return 0;
}


K题

 思路:通过列举样例我们可以找到类似的规律,我们可以将整个字符串进行100100100......类似的进行排列,然后将多余的1排在最后,计算最后那一部分的坏的字符串即可。

#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<string.h>
#include<queue>
#include<vector>
#include<set>
using namespace std;
const int N=1e5+5;  
typedef long long ll;
ll a[N];

void solve()
{
    int n,m;
    cin>>n>>m;
    int x=n-m;
    x/=2;
    if(x==0){
        cout<<n-2<<endl;
    }
    else{
        cout<<max(0,m-x-1)<<endl;
    }

}

int main()
{   
    int t;
    t=1;
    //cin>>t;
    while(t--){
        solve();
    }
    system("pause");
    return 0;
}


M题

思路:dp,dp[i][j]表示给i个人分了j颗糖,然后枚举第i个人分到1-k颗糖,(k<=j)

#include<iostream>
#include<algorithm>
#include<math.h>
#include<map>
#include<string>
#include<string.h>
#include<queue>
#include<vector>
#include<set>
using namespace std;
const int N=1e5+5;  
typedef long long ll;
double dp[505][505];

void solve()
{
    int n,m;
    int i,j,k;
    cin>>n>>m;
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            for(k=1;k<=j;k++){
                dp[i][j]=max(dp[i-1][j-k]+k*1.0/(m-(j-k)),dp[i][j]);
            }
        }
    }
    printf("%.6lf",dp[n][m]);
}

int main()
{   
    int t;
    t=1;
    //cin>>t;
    while(t--){
        solve();
    }
    system("pause");
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值