zzu 2024寒假训练day2(A-D,F-I)

目录

1.A

2.B

3.C

4.D

5.F

6.G

7.H

8.I


题目链接

1.A

每种垃圾大于它的对应垃圾桶的容量时,多出的部分就只能丢入最后一个垃圾桶

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
#define int long long
int r[maxn],a[maxn];
signed main()
{
    int n,c;
    cin>>n>>c;
    for(int i=1;i<=n;i++)cin>>r[i];
    for(int i=1;i<=n;i++)cin>>a[i];
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        if(a[i]>r[i])
        ans+=(a[i]-r[i])*c;
    }
    cout<<ans;
    return 0;
}

2.B

写好结构体的排序规则

#include<bits/stdc++.h>
using namespace std;
const int maxn=305;
#define int long long
struct student{
    int id;
    int chi;
    int math;
    int engl;
    int sum;
};
student a[maxn];
bool cmp(student m,student n)
{
   if(m.sum!=n.sum)return m.sum>n.sum;
   else if(m.chi!=n.chi)return m.chi>n.chi;
   else return m.id<n.id;
}
signed main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        a[i].id=i;
        cin>>a[i].chi>>a[i].math>>a[i].engl;
        a[i].sum=a[i].chi+a[i].math+a[i].engl;
    }
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=5;i++)
    {
        cout<<a[i].id<<" "<<a[i].sum<<"\n";
    }
    return 0;
}

3.C

正常来说都会是接水花费时间少的人先接,所以按接水时间从小到大排序 再用pre[i]=pre[i-1]+a[i-1].first;求得第i个人的等待时间

#include<bits/stdc++.h>
using namespace std;
const int maxn=1005;
pair<int,int> a[maxn];
int pre[maxn];
int main()
{
    int n;
    cin>>n;
    double sum=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].first;
        a[i].second=i;
    }
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++)
    {
        pre[i]=pre[i-1]+a[i-1].first;  
        sum+=pre[i];
        cout<<a[i].second<<" ";
    }
    cout<<"\n";
    printf("%.2f",sum/n);
    return 0;
}

4.D

想要消耗体力最多,容易想到从平地跳到最高点,再跳到最低点,再跳到次高点,再跳到次低点...故从小到大排序,再用两个指针分别指向两端,轮流移动即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[305];
signed main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    sort(a+1,a+1+n);
    int left=0,right=n;
    int sum=0,h1,h2;
    int flag=1;
    while(left<right)
    {
        h1=a[left];
        h2=a[right];
        sum+=pow(h1-h2,2);
        //cout<<"h1=="<<h1<<"h2=="<<h2<<"\n";
        //cout<<"p=="<<pow(h1-h2,2)<<"\n";
        if(flag>0)left++;
        else right--;
        flag*=(-1);
    }
    cout<<sum;
    return 0;
}

5.F

严格的证明我也不会写,但容易想到体重大的牛要往下靠,力量的牛也要往下靠,所以不妨按照体重和力量的总和从小到大排序

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=5e4+5;
struct node{
    int w;
    int s;
};
bool cmp(node m,node n)
{
    return m.w+m.s<n.w+n.s;
}
node a[maxn];
int pre[maxn];
signed main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].w>>a[i].s;
    }
    sort(a+1,a+1+n,cmp);
    int ans;
    for(int i=1;i<=n;i++)
    {
        pre[i]=pre[i-1]+a[i-1].w;
        if(i==1)ans=-a[i].s;
        else ans=max(ans,pre[i]-a[i].s);
    }
    cout<<ans<<"\n";    
    return 0;
}

6.G

要求不重叠的区间最多有多少个

1,第一种思路,开始时间尽可能早,我一开始就这么交上去了只过了一个点,所以细想之后是有问题的

比如[1,100000],[2,4],[4,5],最优是2,而这种思路的结果是1,所以光开始的早不行,结束时间不能太晚

2.结束时间尽可能早,这种思路好像挺有道理的,结束的早,好参加下一场比赛,找不出反例,不妨就这么写

#include<bits/stdc++.h>
using  namespace std;
#define int long long
const int maxn=1e6+5;
struct node{
    int x;
    int y;
};
node a[maxn];
bool cmp(node m, node n) {
   
    return m.y < n.y;
}
signed main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].x>>a[i].y;
    }
    sort(a+1,a+1+n,cmp);
    int end=a[1].y;
    int ans=1;
    for(int i=2;i<=n;i++)
    {
        if(a[i].x<end)continue;
        else
        {
            end=a[i].y;
            ans++;
        }
    }
    cout<<ans;
    return 0;
}

7.H

这个题关键要想到,前面的泥坑被覆盖后,板子可能已经覆盖了后面的泥坑,故用end记录板子覆盖的结尾,如果泥坑被全部覆盖,直接找下个泥坑,如果泥坑被覆盖一部分,把这个泥坑的起始点设为end即可,如果泥坑未被覆盖则不做处理,后面正常算即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e4+5;
struct mud{
    int s;
    int c;
};
mud a[maxn];
bool cmp(mud m,mud n)
{
    return m.s<n.s;
}
signed main()
{
    int n,l;
    cin>>n>>l;
    int ans=0,num,end=0,start=-1;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].s>>a[i].c;
    }
    sort(a+1,a+1+n,cmp);

    for(int i=1;i<=n;i++)
    {
        if(a[i].c<=end)continue;
        if(a[i].s<=end)a[i].s=end;
        num=(a[i].c-a[i].s-1)/l+1;
        ans+=num;
        end=a[i].s+num*l;
    }
    cout<<ans;
    return 0;
}

8.I

这个题可以充分利用大根堆的性质,由于花费的总时间取决于最后一件衣服被烘干的时间,所以只要管湿度最大的那件衣服即可

1.先预处理一天的结果,因为至少要花一天

2.进入循环取堆顶元素,判断堆顶元素k是否大于累计自然风干的的湿度t,如果是则答案就是t/a,不是则循环执行k-=b;sta.push(k),t+=a;即可

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,a,b,w,t,k;
    cin>>n>>a>>b;
    priority_queue<int>sta;
    int ans;
    for(int i=0;i<n;i++)
    {
        cin>>w;
        sta.push(w);
    }
    k=sta.top();
    sta.pop();
    t+=a;
    k-=b;
    sta.push(k);//预处理一天的结果 因为至少需要一天
    while(1)
    {
        k=sta.top();
        sta.pop();
        if(k<=t)
        {
            ans=t/a;
            break;
        }
        k-=b;
        sta.push(k);
        t+=a;
    }
    cout<<ans;
    return 0;
}

还有E,J两道题不会写,择日再补吧.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值