挑战你的智力

gallpoopoo 2005-06-20 09:15:13
有一个建筑物平面,可分解为 m × n 个边长面积均相等的小块,成为“格”
相邻格之间可能有墙, wall ( x , y )表示横坐标为 x 、纵坐标为 y 的格,其四个方向墙取值的加和:左面墙取值 1 ,上面墙取值 2 ,右面墙取值 4 ,下面墙取值 8 。

举例: wall ( 1 , 1 )取值为 3 ,则说明上面和左面有墙,其它方向没有。所有的墙将建筑物分割为若干个互相不连通的区域,每个区域称为一个“房间”。
对于格,及 wall ( x , y )的描述,采用数据文件 input.txt 描述

7

4

11 6 11 6 3 10 6

7 9 6 13 5 15 5

1 10 12 7 13 7 5

13 11 10 8 10 12 13

其中,第一行为 m ,第二行为 n ,第三行各个数据为 wall ( 1 , 1 )—— wall ( 1 , m )其他各行依此类推。

问题:,请编写程序,具体要求如下:
读取一个给定的 input.txt 文件,求解,拆掉哪面墙,可以使得合并的两个房间,获得最大面积。输出夹着该墙的两个格的横纵坐标(只需找到满足要求的一堵墙,各坐标之间使用空格分割,如拆掉( 1 , 1 )和( 1 , 2 )两个格中间的墙,则输出为 1 1 1 2 )。
...全文
173 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
zoohoo 2005-06-21
  • 打赏
  • 举报
回复
#include <iostream>
#include <set>
#include <map>

using namespace std;

class CPointValue
{
public:
CPointValue(void) {}
CPointValue(int x, int y, int value, int num):m_x(x), m_y(y), m_value(value), m_flag(num) {}
~CPointValue(void) {}

bool operator == (const CPointValue &other) const {
return (this->m_x == other.m_x && this->m_y == other.m_y); }

bool operator != (const CPointValue &other) const {
return (this->m_x != other.m_x || this->m_y != other.m_y); }

bool operator < (const CPointValue &other) const {
bool bRes = false;
if(this->m_x < other.m_x)
bRes = true;
else if(this->m_x == other.m_x)
bRes = (this->m_y < other.m_y);
return bRes;
}

bool Connected (const CPointValue &other) const {
bool bRes = false;
if((this->m_x - other.m_x == 0) && (this->m_y - other.m_y == 1)
&& ((this->m_value & 1) == 0) && ((other.m_value & 4) == 0))
bRes = true;
else if((this->m_x - other.m_x == 0) && (this->m_y - other.m_y == -1)
&& ((this->m_value & 4) == 0) && ((other.m_value & 1) == 0))
bRes = true;
else if((this->m_y - other.m_y == 0) && (this->m_x - other.m_x == 1)
&& ((this->m_value & 2) == 0) && ((other.m_value & 8) == 0))
bRes = true;
else if((this->m_y - other.m_y == 0) && (this->m_x - other.m_x == -1)
&& ((this->m_value & 8) == 0) && ((other.m_value & 2) == 0))
bRes = true;

return bRes;
}

void SetValue(int x, int y, int value = 0, int num = 0) {
this->m_x = x, this->m_y = y, this->m_value = value, this->m_flag = num;
}

public:
int m_x; // x坐标
int m_y; // y坐标
int m_value; //
int m_flag; // 是否连通

}; // class CPointValue

typedef set<CPointValue> CPointValueSet;
typedef map<int, int> CMap;
typedef pair<int, int> CPairInt;

class CProcess
{
public:
CProcess(int cols, int rows):m_cols(cols), m_rows(rows) {
this->m_set.clear();
this->m_map.clear();
}
~CProcess(void) {}

void Insert(int x, int y, int value, int num) {
CPointValue pointValue(x, y, value, num);
this->m_set.insert(pointValue);
}

void SetValue(void) {
set<CPointValue>::const_iterator iter, iter2, iterEnd;
iterEnd = this->m_set.end();
for(iter = this->m_set.begin(); iter != iterEnd; iter ++) {
for(iter2 = this->m_set.begin(); iter2 != iterEnd; iter2 ++) {
if(iter == iter2)
continue;
if(iter->Connected(*iter2)) {
if(iter->m_flag < iter2->m_flag) {
const CPointValue *pointValue = (const CPointValue *)(&(*iter2));
CPointValue *point2 = (CPointValue *)pointValue;

point2->m_flag = iter->m_flag;
}
else {
const CPointValue *pointValue = (const CPointValue *)(&(*iter));
CPointValue *point2 = (CPointValue *)pointValue;
point2->m_flag = iter2->m_flag;
}
} // if(iter->Connected(*iter2))
} // for(iter2 = this->m_set.begin(); iter2 != iterEnd; iter2 ++)
} // for(iter = this->m_set.begin(); iter != iterEnd; iter ++)

this->SetMap();

CPairInt first, second;
this->MainProcess(first, second);
this->PrintResult(first, second);
} // SetValue(void)

private:
int m_cols, m_rows;
CPointValueSet m_set;
CMap m_map;

void SetMap(void) {
pair<CMap::iterator, bool> ret;
set<CPointValue>::const_iterator iter, iterEnd;
iterEnd = this->m_set.end();
for(iter = this->m_set.begin(); iter != iterEnd; iter ++) {
ret = m_map.insert(CPairInt(iter->m_flag, 1));
if(!ret.second) {
++ m_map[iter->m_flag];
}
}
}

void MainProcess(CPairInt &first, CPairInt &second) {
set<CPointValue>::const_iterator iter, iterEnd, iterNext;
int iMax = 0, iNow;
CPointValue point;
iterEnd = this->m_set.end();
for(iter = this->m_set.begin(); iter != iterEnd; iter ++) {
if(iter->m_y != this->m_cols && (iter->m_value & 4) == 4) {
point.SetValue(iter->m_x, iter->m_y + 1);
iterNext = this->m_set.find(point);
if(iterNext == iterEnd)
continue;
if(iter->m_flag != iterNext->m_flag) {
iNow = this->m_map[iter->m_flag] + this->m_map[iterNext->m_flag];
if(iMax < iNow) {
iMax = iNow;
first.first = iter->m_x, first.second = iter->m_y;
second.first = iterNext->m_x, second.second = iterNext->m_y;
}
}
} // if(iter->m_y != this->m_cols && (iter->m_value & 4) == 4)
else if(iter->m_x != this->m_rows && (iter->m_value & 8) == 8) {
point.SetValue(iter->m_x + 1, iter->m_y);
iterNext = this->m_set.find(point);
if(iterNext == iterEnd)
continue;
if(iter->m_flag != iterNext->m_flag) {
iNow = this->m_map[iter->m_flag] + this->m_map[iterNext->m_flag];
if(iMax < iNow) {
iMax = iNow;
first.first = iter->m_x, first.second = iter->m_y;
second.first = iterNext->m_x, second.second = iterNext->m_y;
}
}
}
} // for(iter = this->m_set.begin(); iter != iterEnd; iter ++)

cout << first.first << ", " << first.second << ": " << second.first << ", " << second.second << endl;
} // void MainProcess(CPairInt &first, CPairInt &second)

int GetFlag(CPairInt &first) {
CPointValue point;
CPointValueSet::const_iterator iter, iterEnd = this->m_set.end();
point.SetValue(first.first, first.second);
iter = this->m_set.find(point);
if(iter != iterEnd)
return iter->m_flag;
else
return 0;
}

void PrintResult(CPairInt &first, CPairInt &second) {
int iFlag1 = GetFlag(first);
int iFlag2 = GetFlag(second);
if(iFlag1 != iFlag2 && iFlag1 != 0) {
cout << "total number is: " << this->m_map[iFlag1] + this->m_map[iFlag2] << endl;
}
}

}; // class CProcess

int main(int argc, char *argv[])
{
CProcess process(7, 4);
/*
11 6 11 6 3 10 6
7 9 6 13 5 15 5
1 10 12 7 13 7 5
13 11 10 8 10 12 13 */
process.Insert(1, 1, 11, 1);
process.Insert(1, 2, 6, 2);
process.Insert(1, 3, 11, 3);
process.Insert(1, 4, 6, 4);
process.Insert(1, 5, 3, 5);
process.Insert(1, 6, 10, 6);
process.Insert(1, 7, 6, 7);
process.Insert(2, 1, 7, 8);
process.Insert(2, 2, 9, 9);
process.Insert(2, 3, 6, 10);
process.Insert(2, 4, 13, 11);
process.Insert(2, 5, 5, 12);
process.Insert(2, 6, 15, 13);
process.Insert(2, 7, 5, 14);
process.Insert(3, 1, 1, 15);
process.Insert(3, 2, 10, 16);
process.Insert(3, 3, 12, 17);
process.Insert(3, 4, 7, 18);
process.Insert(3, 5, 13, 19);
process.Insert(3, 6, 7, 20);
process.Insert(3, 7, 5, 21);
process.Insert(4, 1, 13, 22);
process.Insert(4, 2, 11, 23);
process.Insert(4, 3, 10, 24);
process.Insert(4, 4, 8, 25);
process.Insert(4, 5, 10, 26);
process.Insert(4, 6, 12, 27);
process.Insert(4, 7, 13, 28);
process.SetValue();

return 0;
}

/*
输出如下:
3, 4: 3, 5
total number is: 14

将已知的资料放入集合中,前3个成员变量分别表示坐标和对应的值,后一个用唯一的整数表示是否连通,如果数字相同即连通。定义方法Connected计算是否连通。map类用于放置连通的标号和数目。最后使用方法MainProcess一一去除隔板找到最大的连通数目
*/
brianlu 2005-06-21
  • 打赏
  • 举报
回复
帮你顶,不过没时间思考了。
aSalt 2005-06-20
  • 打赏
  • 举报
回复
up
「已注销」 2005-06-20
  • 打赏
  • 举报
回复
郁闷。。还以为是iq题。。原来是acm。。。

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧