这道题反过来是uva的测试数据比较水,有严重错误的代码都能ac。
uva虽然过了,但poj tle,测试了一下,应该是b-a==1有点问题,导致一只在循环里面,纠结中。。。(马上又看了一下,原来是rear取得值有问题,poj ac了)
二分掌握的还不是很好,主要是取中间数(姑且就这么叫它吧)的时候,脑子里有点模糊,不过只要想清楚了就好了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAX 600
using namespace std;
char ans[MAX];
int M,K,s[MAX];
long long front,rear;
int state(long long value,int tag)
{
int i,j=0;
long long sum=0;
for(i=M-1;i>=0;i--)
{
if(s[i]>value)
return -1;
sum+=s[i];
if(sum>value)
{
if(tag==1)
{
ans[i]=1;
}
j++;
sum=s[i];
}
}
if(j+1==K)
return 0;
else if(j+1<K)
return 1;
else
return -1;
}
void solve()
{
long long i,j,a,b,value;
a=front,b=rear;
if(state(a,0)>=0)
{
value=a;
state(a,1);
j=1;
for(i=0;i<M;i++)
if(ans[i]==1)
j++;
for(i=0;j<K&&i<M;i++)
{
if(ans[i]==0)
{
ans[i]=1;
j++;
}
}
}
else
{
while(1)
{
if(b-a==1)
{
if(state(a,0)==0)
{
value=a;
state(value,1);
break;
}
value=b;
state(value,1);
j=1;
for(i=0;i<M;i++)
if(ans[i]==1)
j++;
for(i=0;j<K&&i<M;i++)
{
if(ans[i]==0)
{
ans[i]=1;
j++;
}
}
break;
}
if(state((a+b)/2,0)>=0)
b=(a+b)/2;
else
a=(a+b)/2;
}
}
for(i=0;i<M;i++)
{
if(i!=0)
printf(" ");
printf("%d",s[i]);
if(ans[i])
printf(" /");
}
//printf("%d\n",value);
}
int main()
{
int n,i,j;
scanf("%d",&n);
while(n--)
{
scanf("%d %d",&M,&K);
front=0;
memset(ans,0,MAX);
for(i=0;i<M;i++)
{
scanf("%d",&s[i]);
if(s[i]>front)
front=s[i];
}
rear=10000000*(long long)(M/K+2);//有问题,取小了,改成加12ac了
solve();
puts("");
}
return 0;
}