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;
}