Sicily.1041. Pushing Boxes(模拟题)

/*1041. Pushing Boxes
   题目大意:给出一堆盒子,四面墙(各自可以随意移动,左边墙往右移,右边墙往左移...)
             给出一系列移动动作,求出各个盒子的最终位置
             
   思路:分为四个操作:往左,往右,往下,往上。
         例如:往左;这里先拿到可以往左移动的最多位移,然后把盒子按照x坐标,y坐标
               从左到右,从上往下排序(即:x坐标小的在上,y坐标小的在上...)
               然后遍历盒子数组,判断当前盒子是否与上一个盒子在同一行
               如果是:则在上面的左墙y基础上+1,因为:前面的盒子移动可能会推动当前的盒子
                       也移动。 
               如果不是:那么记录左墙移动最大偏移量后的y坐标 
               接着就判断当前的y坐标是否<左墙偏移后的y坐标。如果是,则赋值,否则不发生改变 
*/
#include<iostream>
#include<stdlib.h>
#include<string>
#include<memory.h>
#include<algorithm>
using namespace std;
struct Box{
   int x;
   int y;
   int index;
};

Box box[10];
int row, col, n;
int leftC, rightC, top, bottom;
int rowBoxNum[20];
int colBoxNum[20];
bool isOut(int x, int y){
	 if(x < top || x > bottom || y < leftC || y >rightC )
      return true;
    return false;   
}
int getMaxSameRowBoxNum(int lef, int rig){
	//遍历行,找出间隔内同行最多箱子数目
	int max = 0;
	for(int i = 0; i < row; i++){
		int num = 0;
		//遍历box数组
		for(int k = 0; k<n; k++){
			if(box[k].x == i && box[k].y >= lef && box[k].y <= rig)
				num++;
		}
		//得到每行盒子数目
		//rowBoxNum[i] = num;
		if(num > max)
			max = num;
	}
	return max;
}

int getMaxSameColBoxNum(int top, int bottom){
	//遍历行,找出间隔内同行最多箱子数目
	int max = 0;
	for(int i = 0; i < col; i++){
		int num = 0;
		//遍历box数组
		for(int k = 0; k<n; k++){
			if(box[k].y == i && box[k].x >= top && box[k].y <= bottom)
				num++;
		}
		//得到每列盒子数目
		//rowBoxNum[i] = num;
		if(num > max)
			max = num;
	}
	return max;
}

bool cmpright(const Box &a,const Box &b) {
	if (a.x!=b.x) return a.x<b.x;
	else             return a.y<b.y;
}

bool cmpleft(const Box &a,const Box &b) {
	if (a.x!=b.x) return a.x<b.x;
	else             return a.y>b.y;
}

bool cmpDown(const Box &a,const Box &b) {
	if (a.y!=b.y) return a.y<b.y;
	else             return a.x<b.x;
}

bool cmpUp(const Box &a,const Box &b) {
	if (a.y!=b.y) return a.y<b.y;
	else             return a.x>b.x;
}

void moveLeft(int off){
	int actualOff = rightC -leftC - getMaxSameRowBoxNum(leftC, rightC) +1 < off ? rightC -leftC - getMaxSameRowBoxNum(leftC, rightC) +1 : off ;
	sort(box,box+n,cmpleft);
	int x=-1,y;
	for (int i=0;i<n;i++) {
		//如果不在同一行,那么也就是说他可以直接移动actualOff
		if (box[i].x!=x) {
			x=box[i].x;
			y=rightC-actualOff;
		}
		//如果在与上一个同一行,那么当前要在坐标原基础上-1
		else    y--;
		//如果当前的y坐标大于新的y
		if (box[i].y>y) box[i].y=y;
	}
	
}

void moveRight(int off){
	int actualOff = rightC -leftC - getMaxSameRowBoxNum(leftC, rightC) +1 < off ? rightC -leftC - getMaxSameRowBoxNum(leftC, rightC) +1 : off ;
	sort(box,box+n,cmpright);
	int x=-1,y;
	for (int i=0;i<n;i++) {
		//如果不在同一行,那么也就是说他可以直接移动actualOff
		if (box[i].x!=x) {
			x=box[i].x;
			y=leftC+actualOff;
		}
		//如果在与上一个同一行,那么当前要在坐标原基础上+1
		else    y++;
		//如果当前的y坐标小于新的y
		if (box[i].y<y) box[i].y=y;
	}
	
}

void moveDown(int off){
	int actualOff = bottom -top -  getMaxSameColBoxNum(top, bottom)  +1 < off ? bottom - top -  getMaxSameColBoxNum(top, bottom) +1 : off ;
	sort(box,box+n,cmpDown);
	int x,y=-1;
	for (int i=0;i<n;i++) {
		//如果不在同一列,那么也就是说他可以直接移动actualOff
		if (box[i].y!=y) {
			y=box[i].y;
			x=top+actualOff;
		}
		//如果在与上一个同一列,那么当前要在坐标原基础上+1
		else    x++;
		//如果当前的y坐标小于新的y
		if (box[i].x<x) box[i].x=x;
	}
	
}

void moveUp(int off){
	int actualOff = bottom -top -  getMaxSameColBoxNum(top, bottom)  +1 < off ? bottom - top -  getMaxSameColBoxNum(top, bottom) +1 : off ;
	sort(box,box+n,cmpUp);
	int x,y=-1;
	for (int i=0;i<n;i++) {
		//如果不在同一列,那么也就是说他可以直接移动actualOff
		if (box[i].y!=y) {
			y=box[i].y;
			x=bottom - actualOff;
		}
		//如果在与上一个同一列,那么当前要在坐标原基础上-1
		else    x--;
		//如果当前的y坐标小于新的y
		if (box[i].x>x) box[i].x=x;
	}
	
}


int main()
{

    int testNum = 0;
	 while(cin >> row >> col && row !=0 && col !=0){
		cin >> n;
		
		for(int i=0; i<n; i++){
			cin >> box[i].x >> box[i].y;
			box[i].index = i;
		}
		string operation;
		int offset;
		leftC = 0;
        rightC = col-1;
        top = 0;
        bottom = row-1;
		
		while(cin >> operation && operation != "done") {
			cin >> offset;
			if(operation == "left")
				moveLeft(offset);
			if(operation == "right")
				moveRight(offset);
			if(operation == "up")
				moveUp(offset);
			if(operation == "down")
			    moveDown(offset);
		}
		testNum++;
		cout << "Data set "<< testNum << " ends with boxes at locations";
		sort(box,box+n, cmpright);
		for(int i=0; i<n; i++)
		{
			cout << " (" << box[i].x << "," << box[i].y << ")";
		}
        cout << "." << endl;

     }
    system("pause");
    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值