NYOJ 586狂牛病&POJ 2456(二分検索+欲張り)
狂牛病
時間制限:
1000 ms|メモリ制限:
65535 KB
難易度:
4
説明
農夫Johnは、N(2<=N<=100000)個の仕切りを含む長い畜舎を建て、これらの小さな仕切りはx 1の順に番号が付けられています.xN (0 <= xi <= 1,000,000,000).
しかし、ジョンのC(2<=C<=N)頭牛たちはこのようなレイアウトが好きではなく、数頭の牛を1つの仕切りに置くと、争いが起こる.牛同士を傷つけないように.ジョンは自分で牛に仕切りを割り当てて、任意の2頭の牛の間の最小距離をできるだけ大きくすることにした.では、この最大の最小距離は何だろうか.
入力
複数組のテストデータがあり、EOFで終了します.
1行目:スペースで区切られた2つの整数NとC
2行目-N+1行目:xiの位置をそれぞれ指摘
しゅつりょく
テストデータのセットごとに整数を出力し、問題の最大の最小値を満たし、改行に注意します.
サンプル入力
サンプル出力
この問題を始めたとき、ずっと意味が分からなかった.それからチームメートに聞いてやっと問題の意味が分かった.原題リンク:http://poj.org/problem?id=2456
表題するのは、C頭牛をN個の番号付き仕切りに入れ、任意の2頭牛が位置する仕切り番号の最小差を最大にすることである.例えば、サンプルの順序付けが完了すると1 2 4 8 9になり、1位置に1頭の牛、4位置に1頭の牛が配置され、それらの差は3である.最後の牛は8または9の位置に置いてもよく、4の位置との差はそれぞれ4、5、1の位置の差はそれぞれ7と8で、3より小さくないので、最大の最小値は3です.
解析:これは最小値を最大化する問題です.まず、仕切り番号を小さいものから大きいものに並べ替えると、最大距離は両端の2頭の牛の差を超えず、最小値は0になります.だから、最小値を2分列挙することで求めることができます.現在の最小値がxであると仮定し、最小差がxであると判断した場合、C頭牛を置くことができ、まずxを大きくしてから判断する.入れられない場合は、現在のxが大きすぎることを説明し、xを小さくしてから判断します.最大のxを求めるまでが最終的な答えです.
時間制限:
1000 ms|メモリ制限:
65535 KB
難易度:
4
説明
農夫Johnは、N(2<=N<=100000)個の仕切りを含む長い畜舎を建て、これらの小さな仕切りはx 1の順に番号が付けられています.xN (0 <= xi <= 1,000,000,000).
しかし、ジョンのC(2<=C<=N)頭牛たちはこのようなレイアウトが好きではなく、数頭の牛を1つの仕切りに置くと、争いが起こる.牛同士を傷つけないように.ジョンは自分で牛に仕切りを割り当てて、任意の2頭の牛の間の最小距離をできるだけ大きくすることにした.では、この最大の最小距離は何だろうか.
入力
複数組のテストデータがあり、EOFで終了します.
1行目:スペースで区切られた2つの整数NとC
2行目-N+1行目:xiの位置をそれぞれ指摘
しゅつりょく
テストデータのセットごとに整数を出力し、問題の最大の最小値を満たし、改行に注意します.
サンプル入力
5 3
1
2
8
4
9
サンプル出力
3
この問題を始めたとき、ずっと意味が分からなかった.それからチームメートに聞いてやっと問題の意味が分かった.原題リンク:http://poj.org/problem?id=2456
表題するのは、C頭牛をN個の番号付き仕切りに入れ、任意の2頭牛が位置する仕切り番号の最小差を最大にすることである.例えば、サンプルの順序付けが完了すると1 2 4 8 9になり、1位置に1頭の牛、4位置に1頭の牛が配置され、それらの差は3である.最後の牛は8または9の位置に置いてもよく、4の位置との差はそれぞれ4、5、1の位置の差はそれぞれ7と8で、3より小さくないので、最大の最小値は3です.
解析:これは最小値を最大化する問題です.まず、仕切り番号を小さいものから大きいものに並べ替えると、最大距離は両端の2頭の牛の差を超えず、最小値は0になります.だから、最小値を2分列挙することで求めることができます.現在の最小値がxであると仮定し、最小差がxであると判断した場合、C頭牛を置くことができ、まずxを大きくしてから判断する.入れられない場合は、現在のxが大きすぎることを説明し、xを小さくしてから判断します.最大のxを求めるまでが最終的な答えです.
#include<stdio.h>
#include<algorithm>
using namespace std;
const int N = 100005;
int a[N], n, c;
bool judge(int x)
{
int cnt = 1, tmp = a[0];
for(int i = 1; i < n; i++)
{
if(a[i] - tmp >= x)
{
cnt++;
tmp = a[i];
if(cnt >= c) // C
return true;
}
}
return false;
}
int get_ans() //
{
int l = 0, r = a[n-1] - a[0];
while(l <= r)
{
int mid = (l + r) / 2;
if(judge(mid))
l = mid + 1;
else
r = mid - 1;
}
return l - 1;
}
int main()
{
while(~scanf("%d%d",&n,&c))
{
for(int i = 0; i < n; i++)
scanf("%d",&a[i]);
sort(a, a+n);
printf("%d
",get_ans());
}
return 0;
}