8VC Venture Cup 2016 -C - Block Towers-二分


http://codeforces.com/contest/626/problem/C

C - Block Towers 

//题意:
/*
给你n,m,表示n个学生用高度2的砖堆砌,m个学生用高度为3的钻
要求所有学生堆砌得到的墙高都必须是独一无二的。
其实 n个学生里有人堆出高度 2*3(三块砖),则n个里面的其他人不可以堆2*3
而m个学生里,也不能有高度 3*2 (两块砖)

  求一种方案,使得所有人高度不一样,且最高的高度max_high最小,输出这个max_high
*/ 

就是找n个2的倍数,m个3的倍数的集合,要求他们之间没有重复的,让 集合里面最大值 最小


二分:

下界是max(2n,3m)

上界设为 3(n+m)

每次判断当前的X是否足够分解出  n个学生用长度为2,和,m个学生用长度为3的砖,砌成不同高度的墙

只需要算出 2到x中,整除2的数的个数cun_two,整除3,cun_three,既能除3又能除2cun_com

只需要保证 com-= max(0,n-cun_two);  com+cun_three>m 即可,表明足够找到 n个2的倍数,m个3的倍数,并且他们没有重复

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std; 
__int64 mod=1000000000+7;   
int min(int a,int b)
{return a<b?a:b;}
int max(int a,int b)
{return a>b?a:b;}  
	int n,m;
int bin(int x)
{
	int er=0;
	int san=0;
	int com=0,i;
	for (i=2;i<=x;i++)
	{
		if (i%2==0)
		{
			if (i%3==0) 
			{
				com++; continue;
			}
			else
			er++; 
		}
		if (i%3==0) san++;
	}
	
	if (er<n) com-=n-er;
	if (com+san<m) return 0;

	return 1;

}
int main()
{ 
	int i,j;
	
	cin>>n>>m;
	
	int l=max(2*n,3*m);
	int r=(3*(n+m));
	int ans=-1;
	while(l<=r)
	{
		if (r-l<=1)
		{
			if (bin(l))
				ans=l;
			else
				ans=r;
			break;
		}
		int mid=(l+r)>>1;
		if (bin(mid))
			r=mid;
		else
			l=mid+1;
	}
	printf("%d\n",ans);
	
	return 0;
				
} 


C - Block Towers

//题意:
/*
给你n,m,表示n个学生用高度2的砖堆砌,m个学生用高度为3的钻
要求所有学生堆砌得到的墙高都必须是独一无二的。
其实 n个学生里有人堆出高度 2*3(三块砖),则n个里面的其他人不可以堆2*3
而m个学生里,也不能有高度 3*2 (两块砖)

  求一种方案,使得所有人高度不一样,且最高的高度max_high最小,输出这个max_high
*/ 

二分:

下界是max(2n,3m)

上界设为 3(n+m)

每次判断当前的X是否足够分解出  n个学生用长度为2,和,m个学生用长度为3的砖,砌成不同高度的墙

只需要算出 2到x中,整除2的数的个数cun_two,整除3,cun_three,既能除3又能除2cun_com

只需要保证 com-= max(0,n-cun_two);  com+cun_three>m 即可,表明足够找到 n个2的倍数,m个3的倍数,并且他们没有重复

你可能感兴趣的:(8VC Venture Cup 2016 -C - Block Towers-二分)