hdu 3262



Problem Description
Students often have problems taking up seats. When two students want the same seat, a quarrel will probably begin.

It will have very bad effect when such subjects occur on the BBS.
So, we urgently need a seat-taking-up rule. After several days of argument, the rule finally comes out:
As shown in the figure below, the seats in a classroom form a n×m grid( n rows and m columns), and every cell in the grid represents a seat. The coordinates of the seat in the north-west corner are (1,1) and the coordinates of the seat in the south-east corner seat are (n,m). As you know, some seats make you feel good and some seats don’t. So every seat has a “feeling index”.

Students can take up seats for himself and his friends. Of course, if a seat is already taken up by a student, it can’t be taken up by others. 
For the convenience of communication between friends, when a student is trying to take up seats, he wants all the seats he needs to be consecutive and in the same row. If he can do that, he takes up all the seats he needs, and save the most western one for himself. For example, if a student wants to take up 3 seats, then taking (2,2),(2,3),(2,4) and saving (2,2) for himself is ok; but taking (2,2),(2,4),(2,5) is invalid because those seats are not consecutive. Under the precondition of accomplishing his seat-taking job, a student always wants the “feeling index” of his seat to be as large as possible. 
However, if a student cannot take up all the seats he needs, he will just try to take up only one seat for himself because he doesn’t want to get into the trouble of explaining “Why they can get seats but I can’t?” to some of his friends. Of course he still wants the “feeling index” of his seat to be as large as possible in that situation.
Everyone wants to know where are the seats he can take up .This problem seems a little bit complicated for them. So they want you to write a program to solve the problem.
 

Input
There are several test cases and the input ended by a line of “0 0 0”.
For each test case:
The first line contains three integers: n , m and k ( 1 <= n,m<=30, 1<=k<=50). It means that there are n rows of seats in the classroom and there are m seats in every row. k is the number of students who come into the classroom trying to take up seats.
Following are n lines describing the seats by north to south order .Each line represents a row of seats and contains m integers, indicating the “feeling index” of every seat in that row, by west to east order. “Feeling index” can be fit in a 32-bit integer.
Then k lines follow (We call them k “student lines”). Each line is in the format of “hh:mm q” ( 0 <= hh < 24, 0 <=mm <= 59, 1<=q<=50 ) meaning that a student comes into the classroom at mm minutes past hh o’clock, trying to take up q seats. mm and hh are all two digit integers with possible leading zero, and q is also an integer. Please note that when a student enters the class room, he begins to do his seat taking job immediately and the job takes no time. 
It is guaranteed that the “feeling index” of every seat is different and no students come into the classroom at the same time.
 

Output
You should output k lines for each test case, in the order that correspondent to the above mentioned k “student lines” in the input. Each line must contain two integers indicating the coordinates of the seat which is saved by the student for himself. If the student can’t take up any seats, just output a “-1” instead.
 

Sample Input
  
  
5 5 8 11 12 15 14 13 21 22 25 24 23 16 17 20 19 18 6 7 10 8 9 1 2 5 4 3 09:00 2 09:01 5 09:02 5 09:03 5 09:04 5 09:05 3 09:06 2 09:07 3 0 0 0
 

Sample Output
  
  
2 3 3 1 1 1 4 1 5 1 2 5 2 1 -1
 
题意概括:有一个n*m个座位的教室,每个座位都有其对应的优劣值,然后给你k组提问,每组提问一个时间一个数字,时间代表该时间点会有一个人来到教室,数字代表这个人需要占几个座位。如果能找到多个连续的q个座位,选择最好的(他自己坐在最左边所以连续的位置好坏取决于这些座位的最左边那个),输出连续的座位最左边的坐标,如果一个连续的q个座位都找不到,只需要给自己找一个最好的位置输出这个座位的坐标,如果连一个位置都找不到离开教室输出-1。

解题思路:先把给的数据按照时间排序,然后依次进入教室找位置,如果教室内的空位满足需要的位,那么找出最好的位置把这些位置标记为极小值(找的时候把每一个位置都当成最左边的位置试一下)。如果找不到把剩下的空位遍历一遍找出最好的记录这个位置即可,如果没有空位输出-1。

PS:因为开始按时间顺序把输入样例排序了,但是最好输出要求仍然按照输入的顺序输出对应的结果。

代码:

#include<stdio.h>
#include<algorithm>
using namespace std;
int a[40][40];
struct T
{
    int z,h,m,q,zx,zy,f;
};
struct T t[60];
int cmp(struct T a,struct T b)
{
    if(a.h<b.h)
    return 1;
    else if(a.h==b.h)
    {
        if(a.m<b.m)
        return 1;
        else
        return 0;
    }
    return 0;
}
int cmp1(struct T a,struct T b)
{
    return a.z<b.z;
}
int main()
{
    int i,j,k,l,m,n,b[60],qq;
    long long max;
    while(scanf("%d%d%d",&n,&m,&qq),n+m+qq!=0)
    {
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
                scanf("%d",&a[i][j]);
        for(j=1;j<=n;j++)
            b[j]=m;
        for(i=1;i<=qq;i++)
        {
            t[i].f=0;
            t[i].z=i;
            scanf("%d:%d%d",&t[i].h,&t[i].m,&t[i].q);
        }
        sort(t+1,t+qq+1,cmp);
        /*for(i=1;i<=qq;i++)
            printf("%d %d %d\n",t[i].h,t[i].m,t[i].q);*/
        for(l=1;l<=qq;l++)
        {
            max=-999999999;
            int x;int y;
            long long sum;
            int s=0;
            for(i=1;i<=n;i++)
            {
                if(b[i]==0)
                    s++;
            }
            if(s==n)
            {
                //printf("-1\n");
                t[l].f=0;
                continue;
            }                
            for(i=1;i<=n;i++)
            {
                sum=0;
                if(b[i]>=t[l].q)
                {
                    for(j=1;j<=m-t[l].q+1;j++)
                    {
                        sum=a[i][j];
                        for(k=j;k<j+t[l].q;k++)
                        {
                            if(a[i][k]==-999999999)
                                break;
                        }
                        if(k==j+t[l].q&&max<sum)
                        {    
                            max=sum;
                            x=i;y=j;
                        }
                    }
                }
            }
            if(max==-999999999)
            {
                int mx1=-999999999;
                for(i=1;i<=n;i++)
                {
                    for(j=1;j<=m;j++)
                    {
                        if(mx1<a[i][j])
                        {
                            mx1=a[i][j];
                            x=i;y=j;
                        }
                    }
                }
                b[x]--;
                a[x][y]=-999999999;
            }
            else
            {
                b[x]-=t[l].q;
                for(j=y;j<y+t[l].q;j++)
                    a[x][j]=-999999999;
            }
            //printf("%d %d\n",x,y);
            t[l].f=1;
            t[l].zx=x;
            t[l].zy=y;
        }
        sort(t+1,t+qq+1,cmp1);
        for(i=1;i<=qq;i++)
        {
            if(t[i].f)
            printf("%d %d\n",t[i].zx,t[i].zy);
            else
            printf("-1\n");
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值