【LGR-097】洛谷 11 月月赛 II & ✗✓OI Round 1 Div.2

我还以为打了这个比赛我的名字会变色。。。。。。
比赛链
1.T206821 [✗✓OI R1] 铝锤制作
题目描述

构造一个正整数数列 a,使 a 中所有元素之积为 n,所有元素之和为 k。如果不存在这样的数列,输出 -1。
输入格式

一行两个正整数 n,k

输出格式

第一行一个整数 m,代表这个数列的长度。
接下来一行 m 个正整数 ai​,代表这个数列。要求 1≤m≤1000,1≤ai≤10001。
特别的,如果没有符合要求的数列,直接输出 -1。

本题采用 Special Judge。如果有多种答案,输出任意一种即可。

====================================
做法挺无赖的,找出 n的因数之和最小的情况,小于k就添1做因数,直到添够k

n的因数之和最小的情况都还比k大的话就显然没戏了

#include<bits/stdc++.h>
#define go(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
vector<int>ans;
int main(){
int n,k;
cin>>n>>k;
int nx=n,kx=0;

for(int i=2;i<=n;++i){
    while(nx&&nx%i==0){
        kx+=i;
        if(kx>k){
            cout<<"-1";
            return 0;
        }
        nx/=i;
        ans.push_back(i);
    }
    if(nx<=1){
        break;
    }
}

int dk=k-kx;
int anslen=ans.size()+dk;
cout<<anslen<<endl;
++dk;
while(--dk)
    cout<<"1 ";

for(auto t:ans)
   cout<<t<<" ";

return 0;
}

2.T204284 [✗✓OI R1] 前方之风

题目描述

给出一个长度为 n 的序列 a 和 q 个询问,第 iii 个询问给出 ki​。对于每次询问,你需要进行以下操作:

求出剩下的数的平均数 avg。
将剩下的数中 avg−ki​ 的数删去。
重复以上两个步骤直到所有数都不会被删去。
输出最后会剩下几个数。

注意:询问之间是独立的,也就是说,不会真的删去那些数。
输入格式

本题有多组测试数据。

第一行一个整数 TTT,表示测试数据的数量。
对于每一组数据,第一行两个整数 n,q表示数字个数和询问数量。
接下来一行 nnn 个整数,第 iii 个整数表示 ai。
接下来一行 qqq 个整数,第 iii 个整数表示 ki。
输出格式

输出共 TTT 行,每行输出 qqq 个整数,第 iii 个数表示第 iii 次询问最终会剩下几个数。

======================================

我的做法是暴力模拟,然后用 前缀和、二分优化 一部分

int h0=lower_bound(a+h,a+n+1,avgll-k)-a;
注意这里减的是a

#include<bits/stdc++.h>
#define go(i,a,b) for(int i=a;i<=b;++i)
#define ll long long
using namespace std;
ll a[100000+10];
ll sum[100000+10];

ll avgsolve(int h,int n){

    ll avgll=(sum[n]-sum[h-1])/(n-h+1);
    if((sum[n]-sum[h-1])%(n-h+1))
        ++avgll;
    return avgll;


}


void solve(){
int n,q;
scanf("%d%d",&n,&q);

go(i,1,n){scanf("%lld",&a[i]);}
sort(a+1,a+n+1);

//go(i,1,n){printf("%lld=",a[i]);}
//printf("\n");
go(i,1,n){sum[i]=sum[i-1]+a[i];}


ll k;
go(i,1,q){
    scanf("%lld",&k);
    int h=1;
    while(h<=n){
        ll avgll=avgsolve(h,n);
        int h0=lower_bound(a+h,a+n+1,avgll-k)-a;
        if(h0==h)
            break;

        h=h0;

    }

    printf("%d ",n-h+1);





}

printf("\n");
}






int main(){
int t=1;
cin>>t;
++t;
while(--t){
    solve();

}




return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值