[HDU3262 Seat taking up is tough]

[关键字]:枚举 模拟

[题目大意]:n*m的矩阵,每个矩阵有一个舒适值,给出每个学生进入教室的顺序和它需要占的位子数,只能占连续的一个横条最左边的是他的位置,每次都占他的位置舒适度最大。如果不够则只占它自己的位置,输出他所在的位置的坐标,如果一个位置都不剩就输出-1。

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

[分析]:枚举每一坐标作为自己的位置然后判断其后是否够,如果够就和当前最优指比较。如果都查完都不够就找到全图中可用的最大的舒适度给自己,如果还没有那就输出-1.注意的是每个学生到达的时间不一定是按顺序给出的,所以要先排序。

[代码]:

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

const int MAXN=33;

struct rec
{
int x,y,d;
}ans[MAXN*2];
struct node
{
int h,m,dat,num;
}a[MAXN*2];
int n,m,k;
int map[MAXN][MAXN];
bool b[MAXN][MAXN];

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

bool Init()
{
scanf("%d%d%d",&n,&m,&k);
if (!n && !m && !k) return 0;
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
scanf("%d",&map[i][j]);
for (int i=1;i<=k;++i)
scanf("%d:%d %d",&a[i].h,&a[i].m,&a[i].dat),a[i].num=i;
sort(a+1,a+k+1,cmp);
//for (int i=1;i<=k;++i) printf("%d %d %d %d\n",a[i].num,a[i].h,a[i].m,a[i].dat);
return 1;
}

bool Cleck(int x,int y,int z)
{
for (int i=y;i<=y+z-1;++i)
if (b[x][i]) return 0;
return 1;
}

bool GF(int h)
{
rec Max;
Max.x=Max.y=Max.d=0;
for (int i=1;i<=n;++i)
for (int j=1;j<=m-a[h].dat+1;++j)
if (Cleck(i,j,a[h].dat))
if (map[i][j]>Max.d)
Max.x=i,Max.y=j,Max.d=map[i][j];
if (Max.x && Max.y)
{
ans[a[h].num]=Max;
for (int i=Max.y;i<=Max.y+a[h].dat-1;++i) b[Max.x][i]=1;
return 1;
}
return 0;
}

bool GM(int h)
{
rec Max;
Max.x=Max.y=Max.d=0;
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
if (!b[i][j] && Max.d<map[i][j]) Max.x=i,Max.y=j,Max.d=map[i][j];
if (Max.x && Max.y)
{
ans[a[h].num]=Max,b[Max.x][Max.y]=1;
return 1;
}
return 0;
}

void Solve()
{
memset(ans,0,sizeof(ans));
memset(b,0,sizeof(b));
//printf("%d %d\n",n,m);
for (int i=1;i<=k;++i)
{
if (GF(i)) continue;
if (GM(i)) continue;
ans[a[i].num].d=-1;
}
for (int i=1;i<=k;++i)
if (ans[i].d!=-1) printf("%d %d\n",ans[i].x,ans[i].y); else printf("-1\n");
}

int main()
{
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
while (Init()) Solve();
return 0;
}



转载于:https://www.cnblogs.com/procedure2012/archive/2012/03/13/2393356.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值