CodeForces ——C. Cram Time ( 二分 + 贪心 )

CodeForces ——C. Cram Time
题目链接

解题报告:

贪心的思想,从1开始找一个范围**[1,n]**,读完这个范围内的所有讲义一定就是最多的讲义数啦~~
要读完这个范围所有的讲义需要的时间 time = n*(n+1)/2
emmmmmm二分找一个最佳的n 满足 n*(n+1)/2 <= sum(a+b) 就行好啦,嘻嘻。
可以对n预先优化(当然不优化直接带 n = sum也可以AC ),因为n不可能== sum(a+b) , 而且很容易找出规律n一定接近 sqrt(2 * sum) 也就是 n <= sqrt(2 * sum) 。找到n后,因为1~n内的讲义都能看完,那就从后面贪心选,这样一定能保证最差的情况(刚好用完两天的时间和)
即: n*(n+1)/2 = sum(a+b)时刚好能选完!!!

/*
* @Author: Achan
* @Date:   2018-10-22 20:54:02
* @Last Modified by:   Achan
* @Last Modified time: 2018-10-23 19:51:44
*/
#include<bits/stdc++.h>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector> 
#include<queue>
#include<cmath> 
using namespace std;

#define X 			first
#define Y 			second
#define eps  		1e-2
#define gcd 		__gcd
#define pb 			push_back
#define PI 			acos(-1.0)
#define lowbit(x) 	(x)&(-x)
#define bug 		printf("!!!!!\n");
#define mem(x,y)	memset(x,y,sizeof(x))
#define rep(i,j,k)  for(int i=j;i<(int)k;i++)
#define per(i,j,k)  for(int i=j;i<=(int)k;i++)
#define io std::ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);

typedef long long ll;
typedef long double LD; 
typedef pair<int,int> pii;
typedef unsigned long long ull; 

const int inf  = 1<<30;
const ll  INF  = 1e18 ;
const int mod  = 1e9+7;
const int maxn = 2e5+2;
vector <int > va;
vector <int > vb;
int A[maxn];
int B[maxn]; 


      //#define LOCAL
int main(void)
{
	#ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
	#endif 
	io 
    ll a,b;
    cin>>a>>b;
    ll sum = a+b;
    ll n = sqrt(2*sum);  // n的大概上界 

    ll l = 1; 
    ll r = n;
    while(l<=r) //二分寻找一个最佳的n
    {
    	ll m = (l+r)>>1;	
    	if( (m*(m+1)>>1) <= sum )  //满足a+b 能读到前m本
    	{
    		n = m;  //维护最佳的n
    		l = m+1;
    	}  
    	else r = m-1 ; 
    }
    ll t = n;
    int p,q;
    p = q = 0;
    while(t>0)   //n个数一定都能成功输出,倒着贪心  
    {
    	if(a>=t)  
    	{
    		A[p++] = t; 
    		//va.pb(t);
    		a-=t;
    		t--;
    	}
    	else 
    	{
    		B[q++] = t;
    		//vb.pb(t);
    		b-=t;
    		t--;
    	}
    }

    cout<<p<<endl;
    rep(i,0,p) cout<<A[i]<<" ";
    cout<<endl;

    cout<<q<<endl;
    rep(i,0,q) cout<<B[i]<<" ";
    cout<<endl;

    // cout<<va.size()<<endl;
    // rep(i,0,va.size()) cout<<va[i]<<" ";
    // cout<<endl;
    

    // cout<<vb.size()<<endl;
    // rep(i,0,vb.size()) cout<<vb[i]<<" ";
    // cout<<endl;
}                                                                                      
                                               
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值