icpc济南赛站补题记录 (思维题,区间贪心)

icpc济南赛站补题记录

M:煎饼需要煎两面,一口锅能一次性煎k个饼,一共有n个饼需要煎,煎一面饼要一分钟,问你煎完n张饼需要几分钟
如果k>=n两分钟煎完,否则需要(n*2+k-1)/k分钟
G:给你一个x给你一个y,每次能用一个小于当前x的数异或x,使得最终的x=y
在这里插入图片描述
思路1;
我们知道,一个数异或自己等于0,一个数异或0等于本身,不考虑大小的话,我们直接让x ^ ( x ^ y)即可,如果x ^ y > x 就先让x ^ y,再 ^ x即可(x<x ^ y)

#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long int x,y;
    cin>>x>>y;
    long long int a=x^y;
    if(a>x)
    {
        printf("2\n");
        printf("%lld %lld\n",y,x);
    }
    else
    {
        printf("1\n");
        printf("%lld\n",a);
    }
    return 0;
}

C: 思维题,
在这里插入图片描述
1,2,3堆的石子各有 a , b , c 堆,合并x堆石子和y堆石子的花费是(x * y) mod 3,问你合并所有的石子需要至少多少花费。
首先3堆的石子怎么合并都是0花费不需要考虑,剩下的石子里,我们希望3的倍数堆的石子堆合并最少的次数(花费最少的费用)出现,所以我们先将1堆和2堆里能合成3堆的合并,花费为2,再将剩下的1堆或2堆里的石子合并,1堆三个三个合并花费为3,2堆三个三个合并花费为6,如果剩下一个,直接合并0花费,如果剩下两个,就将两个合并,花费分别为1和4。

原则就是按照花费少的次序将各堆石子合成3的倍数堆

#include<iostream>
using namespace std;
int main()
{
    int a[3];
    cin>>a[0]>>a[1]>>a[2];
    int ans = 0;
    if(a[0]>a[1])
    {
        ans += 2*a[1];
        int tmp = a[0]-a[1];
        ans += (tmp/3)*3;
        if(tmp%3==2)ans+=1;
    }
    else{
        ans += 2*a[0];
        int tmp = a[1]-a[0];
        ans += (tmp/3)*6;
        if(tmp%3==2)ans+=4;
    }
    cout<<ans<<endl;
}

D题 区间贪心
在这里插入图片描述
n个学生写论文,每个学生能写的字数范围为l,r,每个学生能得到的分数为n-k,k为每个学生写字字数的排名(从大到小),这种形势容易造成内卷,如果所有学生选择内卷,他们会写自己能力范围内最多的字,我们不希望内卷,所以希望所有学生写字的总字数最少,而且使学生的成绩不低于原来的目标,问所有学生的最少总字数为多少。

我们考虑贪心,让尽量多的学生成绩排名相同,即让更多的学生写字字数相同,先对r[ i ]从小到大排序,再按l [ i ] 从大到小排序,这样使得落在l ,r之间的点尽量多。遍历时再去区间内l的最大值即可。

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
struct node
{
	int l,r;
}a[N];
int cmp(node x,node y)
{                             
	if(x.r!=y.r)
		return x.r<y.r;
	else return x.l>y.l;
}
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i].l>>a[i].r;
	sort(a+1,a+n+1,cmp);
	int sum=0;
	int maxl=0;
	for(int i=1;i<=n;i++)
	{
		sum+=max(a[i].l,maxl);
		maxl=max(a[i].l,maxl);
	}
	cout<<sum<<endl;
}
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值