[HDU3687 National Day Parade]

[关键字]:枚举+贪心

[题目大意]:给出N*M的矩阵和N*N个点,所有点只能左右移动,问将所有点排列成矩形的最小步数。

//=====================================================================================================================================

[分析]:枚举所构成的矩形的左边界,然后同一行上的每个点一定是按从y值从小到大往枚举的矩形里走,所以先将所有点按x为第一关键字y为第二关键字排序,然后按顺序移入枚举的矩形并计算出步数求最小。

[代码]:

View Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

const int MAXN=11210;
const int INF=0x7fffffff;

struct node
{
int x,y;
}a[MAXN];
int N,M,ans;

int Calc(int sy)
{
int sum=0;
for (int i=1;i<=N;i++)
for (int j=0;j<N;j++)
sum+=abs(a[(i-1)*N+j+1].y-(sy+j));
return sum;
}

bool cmp(node a,node b)
{
if ((a.x<b.x) || ((a.x==b.x) && (a.y<b.y))) return 1;
else return 0;
}

int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
while (scanf("%d%d",&N,&M))
{
if (!N && !M) break;
for (int i=1;i<=N*N;i++) scanf("%d%d",&a[i].x,&a[i].y);
sort(a+1,a+N*N+1,cmp);
//for (int i=1;i<=N*N;i++) printf("%d %d\n",a[i].x,a[i].y);
ans=INF;
for (int i=1;i<=M-N+1;i++)
{
int temp=Calc(i);
//printf("%d %d\n",i,temp);
ans=min(ans,temp);
}
printf("%d\n",ans);
}
return 0;
}



你可能感兴趣的:(HDU)