Codeforces- Educational Codeforces Round 44 (Rated for Div. 2)-A B C D

Codeforces-  Educational Codeforces Round 44 (Rated for Div. 2)


A-Chess Placing

Code A:

/*
思路:对于给定的数组a[],要求把其全部改成1-n的 奇数或偶数,开始题目没看清楚,一直想不明白
怎么装换,比赛完后才发现是固定给出n/2个数。。。,因此是要把1-n中的所有奇数或偶数全部占满,
则只要分别计算奇数偶数的移动次数取最小值即可。 
*/
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

const int MAX_N=105;
int n,m;
int a[MAX_N];

int main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	m=n/2;
	for(int i=0;i<m;++i)
		cin>>a[i];
	sort(a,a+m);
	int s1=0,s2=0;
	for(int i=1;i<=m;++i)
	{
		s1+=abs(2*i-1-a[i-1]);
		s2+=abs(2*i-a[i-1]);
	}
	cout<<min(s1,s2)<<endl;
	
	return 0;
}

B-Switches and Lamps

Code B:

/*
思路:题目关于控制灯是只要开灯了那么就一直不会熄灭。因此只要先求得每个灯的控制种数,
再遍历每个开关,查看它控制的灯是否会由于没有它而熄灭,如果所有的灯都不会熄灭,则说明该开关可以去除掉。 
*/ 
#include<iostream>
using namespace std;

const int MAX_N=2005;
const int MAX_M=2005;
int n,m;
char a[MAX_N][MAX_M];
int d[MAX_M];

int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=0;i<n;++i)
		for(int j=0;j<m;++j)
		{
			cin>>a[i][j];
			d[j]+=a[i][j]-'0';
		}
	bool boo;
	for(int i=0;i<n;++i)
	{
		boo=true;
		for(int j=0;j<m;++j)
			if((d[j]-a[i][j]+'0')==0){
				boo=false;	break;
			}
		if(boo==true)	break;
	}
	if(boo==true)	cout<<"YES"<<endl;
	else	cout<<"NO"<<endl;
	
	return 0;
}


C-Liebig's Barrels

Code C:

/*
思路:贪心,每个桶的最小木块之差不大于l,则要求所有桶的最小木块与最小木块Min之差不大于l ,
而要求所有木桶的最小木块总和的最大值,可以将所有木块a[]由小到大排序,用二分将所有与Min之差大于l的最小下标t找出,
下标r=t-1, 因此对于木桶的最小木块 r ,可以先将>=a[t]的所有木块分配完,之后再将r--来分配每个木桶的k个木块,
这样就能够 a[r]为一个木桶的最小木块,且所取得的所有木桶的最小木块总和最大。 
*/ 
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;

const int MAX_N=100005;
int n,m,h;
int a[MAX_N];

int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>m>>h;
	int N=n*m;
	for(int i=0;i<N;++i)
		cin>>a[i];
	sort(a,a+N);
	int t=lower_bound(a,a+N,a[0]+h+1)-a;
	int l=0,r=t-1,la=a[0];
	LL ans=0;
	while(r>=0){
		int ti=1;
		while(ti<m&&t<N){
			ti++;	t++;
		}
		while(ti<m){
			ti++;	r--;
		}
		ans+=a[r--];
	}
	if(t!=N)	ans=0;
	cout<<ans<<endl;
	
	return 0;
}


D-Sand Fortress

Code D:

/*
思路:由于最左边a[0]<=H, |a[i]-a[i+1]|<=1, 而最右边a[r]必须为 1 ,因此
若 H*(H+1)/2>=n则 为递减顺序,例如  15 5 则 5 4 3 2 1为最优解, 而 17 5则 5 4 3 2 2 1 为最优解,
即 只要找到 x*(x+1)/2>=n的最小值就是最优解
若 H*(H+1)/2<n 则 为先递增后递减的顺序,例如 19 4,则 4 5 4 3 2 1为最优解, 而 22 4,则 4 5 4 3 3 2 1为最优解
因此对于 4 5 4 3 2 1的情况,即 1 2 3 4 5 4 3 2 1去除前面的1 2 3 即x=m*(m-1)/2, 而Max=5, tt=Max*(Max+1)-x-Max;
而对于 tt来说后面还可以插入一个<=Max的数,因此只要找到 sum=tt+Max=Max*(Max+1)-x>=n的最小值,
再判断 sum-Max是否大于等于n,若大于等于则说明不要插入一个数,ans=l*2-m;否则 ans=l*2-m+1;
*/ 
#include<iostream>
using namespace std;
typedef long long LL;

const LL MAX=2e9;
LL n,m;

int main()
{
	ios::sync_with_stdio(false);
	while(cin>>n>>m){
		LL l=1,r=min(m,MAX),ans;
		if(r*(r+1)/2<n){	//由m开始先递增再递减
			LL x=r*(r-1)/2;
			r=MAX;
			while(l<=r){
				LL h=(l+r)/2;
				LL sum=h*(h+1)-x;
				if(sum>=n)	r=h-1;
				else	l=h+1;
			}
			if(l*(l+1)-l-x>=n)	ans=l*2-m;
			else	ans=l*2-m+1;
		}else{	//递减情况 
			while(l<=r){
				LL h=(l+r)/2;
				LL sum=h*(h+1)/2;
				if(sum>=n)	r=h-1;
				else	l=h+1;
			}
			ans=l;
		}
		cout<<ans<<endl;
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/C_13579/article/details/80410678