文章目录
7.23 Codeforces Round 961 (Div. 2)
4 | Codeforces Round 961 (Div. 2) | Jul/23/2024 22:35UTC+8 | 10837 | 1 |
---|
B1 Bouquet (Easy Version)
n种花,a数组是不同花花瓣数,m个币,可以买m个花瓣。花束中任何两朵花的花瓣数之差不能超过 1。最多买几个花瓣
思路
用数组,排序,从前往后,超了,减k,加k+1;
用栈更方便。
代码
int a[200050];
void solve()
{
int n,m,ans=0,sum=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a,a+n+1);
int k=a[1],l=0,x=0;
for(int i=1;i<=n;i++)
{
if(a[i]>m) break;
if(a[i]-k<=1)
{
if(sum>m&&l==0)
continue;
if(a[i]==k)
l++,x=i;
sum+=a[i];
while(sum>m)
{
if(l>0)
sum-=k,l--;
else
sum-=a[i];
}
if(sum<=m)
ans=max(ans,sum);
}
else
{
if(a[i]-a[i-1]==1)
{
k+=1;
i=x;
sum=0;l=0;
}
else
{
k=a[i];
sum=a[i],l=1,x=i;
ans=max(ans,sum);
}
}
}
cout<<ans<<'\n';
}
signed main()
{
IOS
int t;
cin>>t;
while(t--)
solve();
}
B2 Bouquet (Hard Version)
a数组放花瓣数,b数组放花的数量。最多买多少
思路
轻敌了,还想用栈,不断往里面存。写了三个代码,问题:
- vector初始化,resize,再排序,0全放前面了
- vector的insert用错了,应该是push_back
- 这个思路出现的共同问题:bad_alloc,数据太大,push的太多了。
虽然错了,但看到别人更巧的代码。直接用map排序+对应b数组。也有点鸡兔同笼的感觉。
先尽可能选择a[i],剩余的用a[i+1];
在比较(h1,mp[k+1]-h2),最小值就是将a[i]换成a[i+1]的最大值
这里很巧妙的用min,max
代码
int a[N];
signed main()
{
IOS
int t;
cin>>t;
while(t--)
{
int n,m,ans=0;
cin>>n>>m;
map<int,int> mp;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
{
cin>>mp[a[i]];
}
for(auto [k,v] :mp)
{
int q=m;
int h1=min(v,q/k);//k最多选择多少
if(mp.count(k+1)!=0)
{
int h2=min(mp[k+1],(q-h1*k)/(k+1));//在h1基础上,h2最多多少
int sum=min(q,min(h1,mp[k+1]-h2)+h1*k+h2*(k+1));
ans=max(sum,ans);
}
else
ans=max(ans,h1*k);
}
cout<<ans<<'\n';
}
}
C.平方
一个数组可以对任意位进行任意次平方,直到不会出现递减。最少进行多少次。
输入
第一行包含一个整数 t( 1≤t≤1000 ) - 测试用例的数量。随后是测试用例的描述。
对于每个测试用例,第一行包含一个整数 n 数组 a的大小。第二行包含 n( 1≤𝑛≤2⋅10^5 ) 个整数1≤𝑎𝑖≤10^6 )。
思路
又轻敌了,我还以为单纯从前往后遍历一遍呢,没仔细思考,不断平方,数据得多大。**就比如10001,10002,10003…,明明就差1,但还不得不平方。**我的思路实属有点冒犯这一道题啦。
题解上有个浮点数的,还有个整数的。后者更好理解。因为前者涉及到了很多数学上的转化,比如:去对数,有很多对数的公式转化。
我在其中还学到了个东西:
int eps = 1e-9;
1乘10的-9次方,这里表示极小(epsilon),接近于0的极限.
接下来再说整数法:
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
vector<int> v;
void solve() {
int n;
cin >> n;
v.resize(n);
for(auto &i:v)//加&,不然TLE
cin>>i;
for (int i = 1; i < n; i++)
if(v[i-1]>1&&v[i]==1)
{
cout<<"-1\n";//特判
return ;
}
vector<int > ops(n, 0);//初始化
for(int i=1;i<n;i++){
int f=v[i-1];
int b=v[i];
int temp=0;
while(f!=1&&f*f<=b)//如果前面的数小,看一下能接受
temp--,f*=f; //him进行几次平方
while(f>b) //如果大的话,看需要进行几次平方
temp++,b*=b;
ops[i]=max(0ll,ops[i-1]+temp);
}
int ans=0;
for(auto i:ops)
ans+=i;
cout<<ans<<'\n';
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int t;
cin >> t;
while (t--)
solve();
}
。