AcWing 第57 场周赛

115 篇文章 3 订阅
20 篇文章 0 订阅
本文详细介绍了三个算法问题的解决方案。AcWing4485题中,通过枚举比较两个序列的总和来判断大小。AcWing4486题,利用贪心策略找到使数字操作次数最少的方案。AcWing4487题,通过前缀和与动态规划求解最长连续子序列,确保平均值大于100。
摘要由CSDN通过智能技术生成

AcWing 4485. 比大小

思路:
枚举即可,语法题

#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
#define x first
#define y second
#define LL long long 
#define int LL
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define PII pair<int,int>
#define ll_INF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
#define debug(x) cerr << #x << ": " << x << endl
#define io ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
LL Mod(LL a,LL mod){return (a%mod+mod)%mod;}
LL lowbit(LL x){return x&-x;}//最低位1及其后面的0构成的数值
LL qmi(LL a,LL b,LL mod) {LL ans = 1; while(b){ if(b & 1) ans = ans * (a % mod) % mod; a = a % mod * (a % mod) % mod; b >>= 1;} return ans; }
int _;
int n; 
void solve()
{
    cin>>n;
    int s1=0,s2=0;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        s1+=x;
    }
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        s2+=x;
    }
    if(s1>=s2)puts("Yes");
    else puts("No");
}
signed main()
{
    io;
    //cin>>_; 
 // while(_--)
    solve();
    return 0;
}

作者:Leimz
链接:https://www.acwing.com/activity/content/code/content/3669431/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

AcWing 4486. 数字操作

思路:
贪心的角度思考:只乘一次并且很顺利的除下去是操作数最小的,那么我们需要找到那个乘的数字。
n n n进行因式分解, 5184 = 2 6 ∗ 3 4 5184=2^6*3^4 5184=2634
6 , 4 6,4 6,4补成比他们大的最小的 2 2 2的次方也就是 8 8 8
那么给 5184 ∗ 2 2 ∗ 3 4 5184*2^2*3^4 51842234,为什么是8?因为每次求算术平方根,相当于 指 数 / 2 指数/2 /2所以找的是2的次方

#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
#define x first
#define y second
#define LL long long 
#define int LL
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define PII pair<int,int>
#define ll_INF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
#define debug(x) cerr << #x << ": " << x << endl
#define io ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
LL Mod(LL a,LL mod){return (a%mod+mod)%mod;}
LL lowbit(LL x){return x&-x;}//最低位1及其后面的0构成的数值
LL qmi(LL a,LL b,LL mod) {LL ans = 1; while(b){ if(b & 1) ans = ans * (a % mod) % mod; a = a % mod * (a % mod) % mod; b >>= 1;} return ans; }
int _;
int n; 
vector<PII>v;
int maxv;
void get_fact()
{
    for(int i=2;i<=n/i;i++)
    {
        if(n%i==0)
        {
            int s=0;
            while(n%i==0)
            {
                n/=i;
                s++;
            }
            maxv=max(maxv,s);
            v.pb({i,s});
        }
    }
    if(n>1)v.pb({n,1});
}
void solve()
{
    cin>>n;
    get_fact();
    int s=1;
    while(s<maxv)s<<=1;
    bool f=false;
    for(int i=0;i<v.size();i++)
    {
        if(v[i].y<s)
        {
            f=true;
            break;
        }
    }
    int res=f;
    int m=s;
    while(m)
    {
        res++;
        m>>=1;
    }
    res--;
    int ans=1;
    for(int i=0;i<v.size();i++)
    {
        ans*=v[i].x;
    }
    cout<<ans<<' '<<res<<endl;
}
signed main()
{
    io;
 // cin>>_; 
 // while(_--)
    solve();
    return 0;
}

作者:Leimz
链接:https://www.acwing.com/activity/content/code/content/3669771/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

AcWing 4487. 最长连续子序列

思路:
首先对式子进行分析
在这里插入图片描述
相当于求一个最长区间的平均数并且除以100大于零
前缀和表示是 S [ r ] − S [ l − 1 ] > 100 ∗ ( l e n ) S[r]-S[l-1]>100*(len) S[r]S[l1]>100(len)
即:预处理 S [ r ] − 100 ∗ r S[r]-100*r S[r]100r
枚举左端点,找出最大的右端点,如果 r < l r<l r<l不符合,求最长的 l e n len len
这里的 m x mx mx数组时进行二分的关键,因为前缀和数组不一定满足单调性, m x mx mx数组基于动态规划的思想,将 r r r之后的最大值复制给 r r r
同样此题可以用单调栈做。

#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
#define x first
#define y second
#define LL long long 
#define int LL
#define pb push_back
#define all(v) (v).begin(),(v).end()
#define PII pair<int,int>
#define ll_INF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
#define debug(x) cerr << #x << ": " << x << endl
#define io ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
LL Mod(LL a,LL mod){return (a%mod+mod)%mod;}
LL lowbit(LL x){return x&-x;}//最低位1及其后面的0构成的数值
LL qmi(LL a,LL b,LL mod) {LL ans = 1; while(b){ if(b & 1) ans = ans * (a % mod) % mod; a = a % mod * (a % mod) % mod; b >>= 1;} return ans; }
int _;
int n; 
const int N=1e6+10;
int a[N];
int s[N],mx[N];
void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++)s[i]=s[i-1]+a[i];
    for(int i=0;i<=n;i++)s[i]-=100*i;
    mx[n+1]=-ll_INF;
    for(int i=n;i>=0;i--)mx[i]=max(mx[i+1],s[i]);
    int res=0;
    for(int i=0;i<n;i++)
    {
        int l=i+1,r=n;
        while(l<r)
        {
            int mid=l+r+1>>1;
            if(mx[mid]>s[i])l=mid;
            else r=mid-1;
        }
        if(mx[l]<=s[i])continue;
        res=max(res,l-i);
    }
    cout<<res<<endl;

}
signed main()
{
    io;
 // cin>>_; 
 // while(_--)
    solve();
    return 0;
}

作者:Leimz
链接:https://www.acwing.com/activity/content/code/content/3670626/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leimingzeOuO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值