Codeforces Round 961 (Div. 2)

A. Diagonals

----------------------------题解----------------------------------
注意读题,题目中只有i+j相同的格子才是一个对角线,也就是说,(1,1)(2,2)(3,3)的那条大斜线不是个对角线,


如图所示这是一个3*3的图中所有的对角线,那么我们只需要如图所示,从中间往两边依次放就可以,采用暴力做法,我先往中间放满,看有没有剩余,如果有剩余就一次一次判断中间往两边的线有没有放满,i就是对角线能放的线段条数

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k;
        cin>>n>>k;
        int cnt=0;
        if(k!=0)k-=n,cnt++;
        for(int i=n-1;i>=1;i--)
        {  if(k<=0) break;
            else k-=i,cnt++;
            if(k<=0) break;
            else k-=i,cnt++;
            
        }
        cout<<cnt<<'\n';
    }
}

B1. Bouquet (Easy Version)

实验室一个看vtb的🐕说在这个题坠机了,对此我只能评价两个字:单走一个6,**。

--------------------------题解---------------------

从左到右模拟就好,如果剩余的钱还够并且花瓣数符合最大差值不超过1的要求就继续买,否则就让c1++到两个要求都满足的地方,每次取sum的最大值就好。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
ll a[N];
ll b[N];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        ll n,m;
        cin>>n>>m;
        for(ll i=1;i<=n;i++) cin>>a[i];
        ll sum1=0,sum2=0,sum3=0;
        ll c1=1;
        a[0]=a[1];
        sort(a+1,a+1+n);
        for(ll i=1;i<=n;i++)
        {  
            if(sum1+a[i]<=m&&abs(a[i]-a[c1])<=1)
            {
                sum1+=a[i];
            } 
            else { if(a[i]<=m){
                while(sum1+a[i]>m||abs(a[i]-a[c1])>1)
                {
                    sum1-=a[c1];
                    c1++;
                }
                sum1+=a[i];
            }
            else c1=a[i+1],sum1=0;
            }
            sum2=max(sum1,sum2);
        }   
        cout<<sum2<<'\n';
    }
}

B2. Bouquet (Hard Version)

能看到这的都是高手了,我简化语言

---------------------题解------------------------------

这题本质上就是一个思维+模拟。
我们只需要遵循以下策略然后大脑思考一下,就知道是最优的。。
我们先把所有花分成一个一组或者两个一组(可以重复)比如1 2 3 4 10我们就分成以下几组(1.2)(2.3)(3.4)(4.5)(10)这几组

首先保证有一种或两种花瓣种差1的花,我们把它称为小花和大花。。。
如果只有一种很简单不用讲。

如果是两种,我们先把拿小花,(小花拿完或者钱不够),我们都尝试一下看不能不能再买大花(买到钱不够或者大花也买完),此时我们就需要把,没买入的大花与已经买入的小花替换,注意相当于把剩余的大花,已经买入的小花,还有剩下的钱数取个min值加到sum里面去,然后维护最大值

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
 ll n,m;
pair<ll,ll>p[N];
int main()
{
    ll t;
    cin>>t;
    while(t--)
    {
       
        cin>>n>>m;
        for(ll i=1;i<=n;i++) cin>>p[i].first;
        for(ll i=1;i<=n;i++) cin>>p[i].second;
        sort(p+1,p+1+n);
        ll c1=1;
        ll sum=0,ans=0;
        for(ll i=1;i<=n;i++)
        {  sum=0;
        ll cnt1=0,cnt4=0;
        //if(i!=1)c1=i-1;
      // cout<<c1<<endl;
            if(abs(p[i].first-p[c1].first)==1)
            { 
                ll cnt2=m/p[c1].first;
                if(cnt2<=p[c1].second) sum+=cnt2*p[c1].first,cnt1=cnt2;
                else sum+=p[c1].first*p[c1].second,cnt1=p[c1].second;
                ll q=m-sum;
                ll cnt3=q/p[i].first;
                if(cnt3<=p[i].second) sum+=cnt3*p[i].first,cnt4=p[i].second-cnt3;
                else sum+=p[i].first*p[i].second,cnt4=0;
                q=m-sum;
                ll cnt5=min(cnt1,cnt4);
                sum+=min(cnt5,q);
               c1=i; 
            }
            else 
            {  //cout<<1<<endl;
            	
                ll cnt2=m/p[i].first;
               // cout<<cnt2<<endl;
                if(cnt2<=p[i].second) sum+=cnt2*p[i].first,cnt1=cnt2;
                
                else sum+=p[i].first*p[i].second,cnt1=p[i].second;
                c1=i;
            }
            
           
            //cout<<sum<<endl;
            ans=max(ans,sum);
          //  cout<<ans<<endl;
        }
        cout<<ans<<'\n';
    }
}
/*
1
8 100000
239 30 610 122 24 40 8 2
12 13123 112 1456 124 100 123 10982
*/

C. Squaring

这题看了一篇非常好的博客,就引用人家的做法吧

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
ll a[N],f[N];
const double eps=1e-9;
bool check(ll x,ll y,ll f1,ll f2)
{
    double lga=log10(1.0*x),lgb=log10(1.0*y);
    double lglga=log10(1.0*lga),lglgb=log10(1.0*lgb);
    double lg2=log10(2.0);
    return (f1*lg2+lglga+eps>=f2*lg2+lglgb);
}
int main()
{
    ll t;
    cin>>t;
    while(t--)
    {
        ll n;
        cin>>n;
        for(ll i=1;i<=n;i++) cin>>a[i];
        for(ll i=1;i<=n;i++) f[i]=0;
        f[0]=0;
        ll ans=0;
        for(ll i=2;i<=n;i++)
        {
            if(check(a[i],a[i-1],0,f[i-1])) continue;
            
            ll l=0,r=1e10;
            while(l<=r)
            {
                ll mid=(l+r)/2;
                if(check(a[i],a[i-1],mid,f[i-1]))
                {
                    f[i]=mid;
                    r=mid-1;
                }
                else l=mid+1;
            }
            if(f[i]==0)
            {
                ans=-1;
                break;
            }
            ans+=f[i];

        }
        cout<<ans<<'\n';
    }
}

///////////////////KEEP HARD BE THE BEST/////////////////////

posted @ 2024-07-24 21:52  marisa3  阅读(19)  评论(0编辑  收藏  举报