http://codeforces.com/contest/10/problem/B
题目大意:
n波人去k*k的电影院看电影。要尽量往中间坐,往前坐。优先考虑中间
没想到什么好的办法。。xjb暴力贪心,用个树状数组辅助一下查询时减轻复杂度。。
复杂度 n*k*k*logk.........n=1000,k=100
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include<stack>
using namespace std;
int tm[1005];
const int inf=2147483647;
int tree[105][105*4];
int lowbit(int x)
{return x&(-x);}
void add(int x,int value,int id)
{
for (int i=x;i<=100;i+=lowbit(i))
tree[id][i]+=value;
}
int get(int x,int id)
{
int sum=0;
for (int i=x;i;i-=lowbit(i))
sum+=tree[id][i];
return sum;
}
int main()
{
int i ,j,k;
int n,m;
cin>>n>>m;
for (i=1;i<=n;i++)
{
scanf("%d",&tm[i]);
}
int xx=ceil(1.0*m/2);
int yy=xx;
for (k=1;k<=n;k++)
{
int num=tm[k];
int ans=inf;
int minx,miny=1;
for (i=1;i<=m;i++)
{
for (j=1;j+num-1<=m;j++)
{
int ret=get(j+num-1,i)-get(j-1,i);
if (ret!=0)continue;
int tmp=abs(xx-i)*num;
if (j>=yy)
tmp+= (j+j+num-1)*(num)/2-num*yy;
else
if (j+num-1<=yy)
tmp+=num*yy-(j+j+num-1)*(num)/2;
else
tmp+=yy*(yy-j+1)-(j+yy)*(yy-j+1)/2+(j+num-1+yy+1)*(j+num-1-(yy+1)+1)/2-yy*(j+num-1-(yy+1)+1);
if (tmp<=ans)
{
if (tmp<ans)
{
ans=tmp;
minx=i;
miny=j;
}
else
{
if (i<minx)
{
minx=i,miny=j;
}
else
if (i==minx)
{
if (j<miny)
{
miny=j;
}
}
}
}
}
}
if (ans!=inf)
{
printf("%d %d %d\n",minx,miny,miny+num-1);
for (i=miny;i<=miny+num-1;i++)
add(i,1,minx);
}
else
printf("-1\n");
}
return 0;
}