| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
Re:这样的做法可以证明是正确的吗?In Reply To:这样的做法可以证明是正确的吗? Posted by:harvard at 2005-05-11 16:45:25 正确,靠这个思路AC的。
AC代码:
/*
思路:每次从左边到右边扫描每列
如果大于K,删除最右边的那个(那个影响最大)
*/
#include<stdio.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#define Max 1010
#define inf 0x3f3f3f3f
#define max(a,b) a>b?a:b;
#define min(a,b) a>b?b:a;
using namespace std;
struct Node{ //优先队列排序
int id;
int cnt;
};
struct cmp{ //从大到小
bool operator()(Node one,Node two)
{
return one.cnt<two.cnt;
}
};
priority_queue<Node ,vector<Node>,cmp> q; //大根堆
void swap(int &x,int &y) //交换,因为可能从右到左给数据
{
int c=y;
y=x,x=c;
}
int map[Max][Max]; //保存所有的墙标记
int ok[Max]; //保存墙的数量
int del[Max]; //保存的是是否删除
int main()
{
int t,n,k,stx,sty,endx,endy,x,y,max_y,max_x,ans;
Node temp;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
max_y=-1;
max_x=-1;
ans=0;
memset(map,0,sizeof(map));
memset(del,0,sizeof(del));
memset(ok,0,sizeof(ok));
for(int i=1;i<=n;i++)
{
scanf("%d%d%d%d",&stx,&sty,&endx,&endy);
if(stx>endx) //交换,数据有坑
{
swap(stx,endx);
}
max_x=max(max_x,endx);
max_y=max(max_y,sty);
for(int j=stx;j<=endx;j++)
{
map[sty][j]=i;
}
ok[i]=endx-stx+1;//有多少个墙
}
while(q.size()) q.pop();
for(int i=0;i<=max_x;i++)
{
int laji=0;
for(int j=0;j<=max_y;j++)
{
if(map[j][i]&&!del[map[j][i]])// 有数并且没有被删除
{
laji++;
temp.id=map[j][i];
temp.cnt=ok[temp.id];//还有多少个点
q.push(temp);
}
}
while(q.size()>k) //一直到全部满足
{
temp=q.top();
q.pop();
ans++; //每删除一个 ++
del[temp.id]=1; //删除
}
while(q.size()) //点数全部减少
{
temp=q.top();
q.pop();
ok[temp.id]--;
}
}
printf("%d\n",ans);
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator