POJ 3829 Seat taking up is tough

题目大意:

        现在要模拟一个帮同学占座的过程,教室有n行m列座位(1 ≤ n, m ≤ 30),左上角坐标为(1, 1),右下角坐标为(n, m),每个座位都有一个舒适度(32位整型),当一位同学来到教室后他会先看看是否能帮自己的小伙伴一块儿占座,他和他的小伙伴必须坐在同一行并且是连续的,如果位子已经被之前的同学占去则不能占,并且他本人必须坐在最左边的一个座位,如果可以帮小伙伴占座则他本人的座位必须是所有情况中舒适度最高的,但是如果因为座位占的比较多而无法帮所有小伙伴都抢到座位就不帮小伙伴占座而只给自己占座了,同样只给自己占座的舒适度也必须是所有情况中最高的,如果一个位子都没了则自己也就没有位子坐了。

        现有多个测例,每个测例中都给出n、m和k,k表示总共有k个学生前来占座(1 ≤ k ≤ 50),测例以n, m, k = 0表示结束,接下来给出舒适度的n×m矩阵,接下来给出k个学生到达教室的时间以及帮多少个小伙伴占座,形式为"hh:mm q",其中0 ≤ hh < 24,0 ≤ mm <60,1 ≤ q ≤ 50,其中hh和mm会有前导0,学生到教室后立即开始占座,占座不需要时间,输入保证每个位子的舒适度都是不同的并且没有学生在同一时间到达教室,对于每个测例,要求按照输入时的学生的顺序输出每个学生为自己占到作为的坐标,形式为"x y",无需输出帮小伙伴占到的座位的坐标,如果自己没有占到作为则输出"-1"即可。

题目链接

注释代码:

/*                                                
 * Problem ID : POJ 3829 Seat taking up is tough
 * Author     : Lirx.t.Una                                                
 * Language   : C++                               
 * Run Time   : 16 ms                                                
 * Run Memory : 144 KB                                                
*/ 

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>

//k表示有多少个学生要来上课
#define	MAXK		50
//n表示总共多少排座位
#define	MAXN		31

using namespace std;

struct	Stud {

	int		t;//time,学生到达教室的时间(按分钟计,比如2:30就是150)
	int		n;//表示要为多少同学占座
	int		x, y;//表示该同学所占到的座位的坐标
	int		id;//学生的编号
};

int		n, m;//座位共有n排m列

Stud	s[MAXK];//student,表示每个来占座的学生

int		val[MAXN][MAXN];//每个座位的舒适度,为int型整数
bool	ocp[MAXN][MAXN];//is occupied,表示一个座位是否被占

bool
srchfor_coleg(Stud &ss) {//search for colleague
	//为同学占座
	//如果都能占到则返回true否则为false

	int		i, j, k;//计数变量
	int		mm;//表示每排扫描的最后一个位置
	int		max;

	int		x, y;//可行解

	bool	ok;

	mm = m - ss.n + 1;//从超过该位置的地方开始扫描人数一定不足ss.n个

	max = 0;//为自己挑到的最大舒适值
	for ( i = 1; i <= n; i++ )
		for ( j = 1; j <= mm; j++ )//从一排中从头到尾扫描
			if ( !ocp[i][j] ) {//如果没被占就从该位置开始扫描
			
				ok = true;//表示以(i, j)为开头的ss.n个座位可行(即可被占)
				for ( k = 0; k < ss.n; k++ )
					if ( ocp[i][j + k] ) {//如果ss.n个座位不能连续则表示不成功
					
						ok = false;
						break;
					}

				if ( ok && val[i][j] > max ) {//如果连续ss.n个座位可行并且val[i][j]值较大
					//则更新max
				
					x = i;
					y = j;

					max = val[i][j];
				}
			}

	if ( max ) {//如果max不为0就表示有可行解
	
		ss.x = x;
		ss.y = y;

		for ( k = 0; k < ss.n; k++ )//ss.n个座位都占掉
			ocp[x][y + k] = true;

		return true;
	}

	return false;//无可行解
}

void
srchfor_slf(Stud &ss) {//search for self
	//为自己占座

	int		i, j;//计数变量
	int		x, y;//可行解
	int		max;//最佳舒适度

	max = 0;
	for ( i = 1; i <= n; i++ )
		for ( j = 1; j <= m; j++ )
			if ( !ocp[i][j] && val[i][j] > max ) {//满教室找即可
			
				x = i;
				y = j;

				max = val[i][j];
			}

	if ( max ) {
	
		ss.x = x;
		ss.y = y;

		ocp[x][y] = true;
	}
}

bool
t_fcmp(const Stud &s1, const Stud &s2) {//按照到教室的时间排序

	return s1.t < s2.t;
}

bool
id_fcmp(const Stud &s1, const Stud &s2) {//按照输入顺序排序

	return s1.id < s2.id;
}

int
main() {

	int		k;//到教室占座的学生的个数

	int		hh, mm;//小时和分钟

	int		i, j;//计数变量

	while ( scanf("%d%d%d", &n, &m, &k), n ) {
	
		memset(ocp, false, sizeof(ocp));//占座情况清空

		for ( i = 1; i <= n; i++ )
			for ( j = 1; j <= m; j++ )
				scanf("%d", &val[i][j]);

		for ( i = 0; i < k; i++ ) {
		
			scanf("%d:%d%d", &hh, &mm, &s[i].n);

			s[i].t  = hh * 60 + mm;
			s[i].x  = 0;
			s[i].y  = 0;
			s[i].id = i;
		}

		sort(s, s + k, t_fcmp);//按照到教室时间排序

		for ( i = 0; i < k; i++ )//先为同学找座,如果找不到再为自己找座
			if ( !srchfor_coleg(s[i]) )
				srchfor_slf(s[i]);

		sort(s, s + k, id_fcmp);//最后输出时要求按照输入时的顺序输出

		for ( i = 0; i < k; i++ )
			if ( s[i].x )//占到座则输出座位的坐标
				printf("%d %d\n", s[i].x, s[i].y);
			else//x,y为初始化的值0,表示没占到座
				puts("-1");
	}

	return 0;
}

无注释代码:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>

#define	MAXK		50
#define	MAXN		31

using namespace std;

struct	Stud {

	int		t;
	int		n;
	int		x, y;
	int		id;
};

int		n, m;

Stud	s[MAXK]; 

int		val[MAXN][MAXN];
bool	ocp[MAXN][MAXN];

bool
srchfor_coleg(Stud &ss) {

	int		i, j, k;
	int		mm;
	int		max;

	int		x, y;

	bool	ok;

	mm = m - ss.n + 1;

	max = 0;
	for ( i = 1; i <= n; i++ )
		for ( j = 1; j <= mm; j++ )
			if ( !ocp[i][j] ) {
			
				ok = true;
				for ( k = 0; k < ss.n; k++ )
					if ( ocp[i][j + k] ) {
					
						ok = false;
						break;
					}

				if ( ok && val[i][j] > max ) {
				
					x = i;
					y = j;

					max = val[i][j];
				}
			}

	if ( max ) {
	
		ss.x = x;
		ss.y = y;

		for ( k = 0; k < ss.n; k++ )
			ocp[x][y + k] = true;

		return true;
	}

	return false;
}

void
srchfor_slf(Stud &ss) {

	int		i, j;
	int		x, y;
	int		max;

	max = 0;
	for ( i = 1; i <= n; i++ )
		for ( j = 1; j <= m; j++ )
			if ( !ocp[i][j] && val[i][j] > max ) {
			
				x = i;
				y = j;

				max = val[i][j];
			}

	if ( max ) {
	
		ss.x = x;
		ss.y = y;

		ocp[x][y] = true;
	}
}

bool
t_fcmp(const Stud &s1, const Stud &s2) {

	return s1.t < s2.t;
}

bool
id_fcmp(const Stud &s1, const Stud &s2) {

	return s1.id < s2.id;
}

int
main() {

	int		k;

	int		hh, mm;

	int		i, j;

	while ( scanf("%d%d%d", &n, &m, &k), n ) {
	
		memset(ocp, false, sizeof(ocp));

		for ( i = 1; i <= n; i++ )
			for ( j = 1; j <= m; j++ )
				scanf("%d", &val[i][j]);

		for ( i = 0; i < k; i++ ) {
		
			scanf("%d:%d%d", &hh, &mm, &s[i].n);

			s[i].t  = hh * 60 + mm;
			s[i].x  = 0;
			s[i].y  = 0;
			s[i].id = i;
		}

		sort(s, s + k, t_fcmp);

		for ( i = 0; i < k; i++ )
			if ( !srchfor_coleg(s[i]) )
				srchfor_slf(s[i]);

		sort(s, s + k, id_fcmp);

		for ( i = 0; i < k; i++ )
			if ( s[i].x )
				printf("%d %d\n", s[i].x, s[i].y);
			else
				puts("-1");
	}

	return 0;
}

单词解释:


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值