R6

A

思路:

d p [ i ] dp[i] dp[i]代表以 a [ i ] a[i] a[i]结尾的序列最长有多长,然后对于每个 d p [ i ] dp[i] dp[i]之前的 1 1 1 i − 1 i-1 i1遍历找一个最大值进行取代即可

代码:

#include<stdio.h>
#include<math.h>
#include<algorithm>
#define LL long long
using namespace std;
const int mod=998244353;
const int MAXN=3e5+7;
LL a[MAXN],dp[MAXN],c[MAXN];
int main()
{
    int n;
    while(~scanf("%d",&n)){
        for(int i=0;i<n;i++) scanf("%lld",&a[i]);
        LL ans=-MAXN;
        for(int i=0;i<n;i++){
            dp[i]=1;
            for(int j=0;j<i;j++){
                if(a[i]>a[j]) dp[i]=max(dp[j]+1,dp[i]);
            }
            ans=max(ans,dp[i]);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

C

思路

( k / 2 ) ∗ a − ( k / 2 ) ∗ b + ( k % 2 ) ∗ a (k/2)*a-(k/2)*b+(k\%2)*a (k/2)a(k/2)b+(k%2)a算出数据即可

代码

#include<stdio.h>
#include<math.h>
#include<algorithm>
#define LL long long
using namespace std;
const int mod=998244353;
const int MAXN=3e5+7;
LL a[MAXN],dp[MAXN],c[MAXN];
int main()
{
    int n;scanf("%d",&n);
    while(n--){
        LL a,b,k;
        scanf("%lld%lld%lld",&a,&b,&k);
        printf("%lld\n",(k/2)*a-(k/2)*b+(k%2)*a);
    }
    return 0;
}

D

思路

满足 101 101 101的就把1往前提然后计数即可

代码

#include<stdio.h>
#include<math.h>
#include<algorithm>
#define LL long long
using namespace std;
const int mod=998244353;
const int MAXN=2e6+7;
int vis[MAXN],k[MAXN],a[MAXN];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",&a[i]);
    int ans=0;
    for(int i=1;i<n;i++){
        if(a[i]==0&&a[i-1]==1&&a[i+1]==1){
            a[i+1]=0;
            ans++;
        }
    }
    printf("%d\n",ans);
    return 0;
}

E

思路

既然是要求去掉一个数后存在一个数等于其他所有数之和,那么剩下的所有数之和肯定是偶数。
两种思路,二分找数或者设置映射判断是否存在。在判断遍历去掉时我们需要注意一点,如果去掉的这个数有两个,那么我们需要特判一下。

代码

#include<stdio.h>
#include<math.h>
#include<algorithm>
#define LL long long
using namespace std;
const int mod=998244353;
const int MAXN=2e6+7;
int vis[MAXN],k[MAXN],a[MAXN];
int main()
{
    int n;
    while(~scanf("%d",&n)){
        LL sum=0;
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            vis[a[i]]++;
            sum+=a[i];
        }
        int cnt=0;
        for(int i=0;i<n;i++){
            LL temp=sum-a[i];
            if((temp<=MAXN)&&(temp%2==0)){
                temp/=2;
                if(temp!=a[i]&&vis[temp]>=1) k[cnt++]=i+1;
                else if(vis[temp]>=2) k[cnt++]=i+1;
            }
        }
        printf("%d\n",cnt);
        for(int i=0;i<cnt;i++) printf("%d ",k[i]);
    }
    return 0;
}

F

思路

二分求存在的子序列的遍数最大值,然后往外出数即可。去重可以用deque也可以像我一样用映射。

代码

#include<stdio.h>
#include<math.h>
#include<algorithm>
#define LL long long
using namespace std;
const int mod=998244353;
const int MAXN=2e6+7;
struct v{
    int pos,wi;
}vis[MAXN];
int n,k;
struct da{
    int w,num;
}d[MAXN];
bool cmp(da a,da b){return a.num>b.num;}
bool check(int mid,int cnt){
    int sum=0;
    for(int i=0;i<cnt;i++) sum+=d[i].num/mid;
    return sum>=k;
}
int main()
{
    int temp,cnt=0;
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++){
        scanf("%d",&temp);
        if(!vis[temp].wi){d[cnt++].w=temp;vis[temp].pos=cnt-1;}
        vis[temp].wi++;
        d[vis[temp].pos].num=vis[temp].wi;
    }
    sort(d,d+cnt,cmp);
    int l=1,r=1e9,ans=0;
    while(l<=r){
        int mid=(l+r)/2;
        if(check(mid,cnt)) l=mid+1;
        else r=mid-1,ans=r;
    }
    
    for(int i=0;i<cnt;i++){
        if(k==0) break;
        int t=d[i].num/ans;
        while(t--){
            printf("%d ",d[i].w),k--;
            if(k==0) break;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值