/*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;
}
Sicily.1041. Pushing Boxes(模拟题)
最新推荐文章于 2019-04-16 12:31:06 发布