Codeforces edu 88(A~E)

A题.Berland Poker

读懂题意即可
代码:

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

int main()
{
    
    
    ll t,n,m,k;
    scanf("%lld",&t);
    while(t--)
    {
    
    
        scanf("%lld %lld %lld",&n,&m,&k);
        ll op=n/k;
        if(m<=op)
        {
    
    
            printf("%lld\n",m);
            continue;
        }
        else
        {
    
    
            ll ans=op;
            m-=op;
            ll u=k-1;
            if(m%u==0)
            {
    
    
                printf("%lld\n",ans-m/u);
            }
            else
            {
    
    
                ans=ans-(m/u+1);
                printf("%lld\n",ans);
            }
        }
    }
    return 0;
}

B题.New Theatre Square

只能选1 x 1 或 1 x 2的,如果1x1的价格的两倍小于1x2的,那么就全部用1x1的,否则能用1x2的就用1x2的
代码:

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

char s[105][10005];
int main()
{
    
    
    ll t,n,m,k,x,y;
    scanf("%lld",&t);
    while(t--)
    {
    
    
        scanf("%lld %lld %lld %lld",&n,&m,&x,&y);
        for(int i=0;i<n;i++)
        {
    
    
            scanf("%s",s[i]);
        }
        if(2*x<=y)
        {
    
    
            ll cnt=0;
            for(int i=0;i<n;i++)
            {
    
    
                for(int j=0;j<m;j++)
                {
    
    
                    if(s[i][j]=='.')
                    {
    
    cnt++;}
                }
            }
            printf("%lld\n",cnt*x);
        }
        else
        {
    
    
            ll sx=0,sy=0;
            for(int i=0;i<n;i++)
            {
    
    
                int j=0;
                while(j<m)
                {
    
    
                    if(j<m-1)
                    {
    
    
                        if(s[i][j]=='.'&&s[i][j+1]=='.')
                        {
    
    sy++;j+=2;continue;}
                        if(s[i][j]=='.'&&s[i][j+1]!='.')
                        {
    
    sx++;j++;continue;}
                        j++;
                    }
                    else
                    {
    
    
                        if(s[i][j]=='.')
                        {
    
    sx++;j++;continue;}
                        j++;
                    }
                }
            }
            printf("%lld\n",sx*x+sy*y);
        }
    }
    return 0;
}

C题.Mixing Water

题意:有两种水,一种热水温度为h,一种凉水温度为c,只能按照一杯热水、一杯凉水、一杯热水、一杯凉水······的顺序添加到同一个桶中,问最少需添加几次,使得桶中水的平均温度最接近t
思路:因为精度问题WA了两次很难受,这题推一个式子即可,当添加次数为偶数时,桶内温度一定为(h+c)/2
设当添加次数为j,且j为奇数时,可得到这样一个式子:(((j-1)/2)*(h+c)+h)/j=t
这样可以把 j 解出来,j可能是个浮点数,只是个模糊数值吧,把j附近的整数枚举一遍求出最终的答案
代码:

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

char s[105][10005];
int main()
{
    
    
    ll t,h,c,f;
    scanf("%lld",&t);
    while(t--)
    {
    
    
        scanf("%lld %lld %lld",&h,&c,&f);
        if(h<=f)
        {
    
    printf("1\n");
        continue;}
        double hh=h*1.0;
        double cc=c*1.0;
        double ff=f*1.0;
        //double all=0;
        double op=(hh+cc)/2.0;
        if(ff<=op)
        {
    
    printf("2\n");continue;}
        double ans=(hh-cc)/(ff*2.0-hh-cc);
        double opc=ff-op;
        ll df=ans;
        ll pos;
        double minn=99999999.0;
        for(ll i=df-3;i<=df+3;i++)
        {
    
    
            if(i<=0){
    
    continue;}
            if(i%2==0)
            {
    
    
                double uu=ff-op;
                if(uu<=minn)
                {
    
    pos=i;minn=uu;}
            }
            else
            {
    
    
                double ee=(((i-1)/2)*(h+c)*1.0+h*1.0)/(i*1.0);
                double uu=fabs(ee-ff);
                if(uu<minn)
                {
    
    
                    pos=i;
                    minn=uu;
                }
            }
        }
        if(pos%2==0)
        {
    
    printf("2\n");}
        else
        {
    
    printf("%lld\n",pos);}
    }
    return 0;
}

待更新·································先打lol去了

D题.Yet Another Yet Another Task

又是最后剩下半个小时,写了个假DP WA了好几次,唉。。。。
题意:求一段区间,使该区间去掉一个最大值后的区间和值最大,问区间和最大值是多少
思路:因为ai<=30,直接从0到30枚举最大值,对每次最大值求最大子段和
代码:

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

ll a[200005],d[200005];
int main()
{
    
    
    ll n;
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
    
    scanf("%lld",&a[i]);}
    ll ans=-9999999999999;
    for(int i=0;i<=30;i++)
    {
    
    
        ll maxx=-9999999999999;
        for(int j=1;j<=n;j++)
        {
    
    
            if(a[j]>i)
            {
    
    d[j]=0;}
            else
            {
    
    d[j]=max(d[j-1]+a[j],(ll)0);
            maxx=max(maxx,d[j]);}
        }
        ans=max(ans,maxx-i);
    }
    printf("%lld\n",ans);
    return 0;
}

E题.Modular Stability

题意:给你一个n和k,要求在1~n内取k个数,对于任何正数x,x%这k个数任何排列方式后的值相同,问有多少种取法
思路:仿照样例1打个表,差不多就知道是咋回事了
再用组合数和逆元求出最终结果
代码:

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

ll mod=998244353,bb=1;
void init(ll r)
{
    
    
    for(ll i=r;i>=1;i--)
    {
    
    bb=bb*i%mod;}
}
ll apow(ll a,ll b)
{
    
    
    ll s=1;
    while(b)
    {
    
    
        if(b&1)
        {
    
    s=s*a%mod;}
        a=a*a%mod;
        b>>=1;
    }
    return s%mod;
}
ll C(ll n,ll r)
{
    
    
    ll aa=1;
    //cout<<n<<" "<<r<<endl;
    for(ll i=n;i>=n-r+1;i--)
    {
    
    aa=aa*i%mod;}
    return aa*apow(bb,mod-2)%mod;
}
int main()
{
    
    
    ll n,k;
    cin>>n>>k;
    if(n==k){
    
    cout<<"1"<<endl;return 0;}
    if(n<k){
    
    cout<<"0"<<endl;return 0;}
    if(k==1){
    
    cout<<n<<endl;return 0;}
    init(k-1);
    ll ans=0;
    for(ll i=1;i<=n;i++)
    {
    
    
        if(i+k>n)
        {
    
    break;}
        ll maxx=n/i;
        if(maxx<k){
    
    continue;}
        ans=(ans%mod+C(maxx-1,k-1)%mod)%mod;
    }
    cout<<ans<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43781431/article/details/106432374