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/////////////////////