开空调后房间墙壁潮湿有水珠
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开空调后房间墙壁潮湿有水珠相关的知识,希望对你有一定的参考价值。
参考技术A开空调后房间墙壁潮湿有水珠
开空调后房间墙壁潮湿有水珠,空调是日常生活中起到不小的帮助,不管是炎热的夏天还是寒冷的冬天,都会用到空调,但是有不少人会反映开空调后房间墙壁潮湿有水珠,下面一起来探讨开空调后房间墙壁潮湿有水珠。
开空调后房间墙壁潮湿有水珠1
房间内空气中的水分碰到墙壁液化产生的水珠。
冬天房间内的温度较低,正常情况下墙壁的温度是和空气中一样的。当开启空调开热风后,因为情况的比热容比较小而且空调吹热风首先接触的就是房间内的空气,所以房间内的\'空气温度上升会比墙壁温度上升快很多。
当空调开热风一段时间后,房间内空气和墙壁就会有一定的温差。空气较热而墙壁较冷,空气中的水分碰到冰冷的墙壁就会迅速降温发生液化,从气态变为液态。慢慢的液化的水就会凝聚到一起形成水珠。
扩展资料:
冬天房间空调开热风墙上会有水珠是因为液化——空气中水分从气态变为液态的过程。液化是汽化的逆过程,是气体分子相互吸引而凝结成为液体。液化时物质放出热量。在临界温度以下的气体,都可以液化。
冬天房间空调开热风可能会导致空气干燥,可以使用下面方法缓解:
1、避免长时间呆在空调房间里。
2、如果有条件最好把室温恒定在24℃左右,室内外温差别超过7℃,还要经常开窗换气,确保室内外空气的对流。
3、空调开机1-3小时最好关一段时间空调,打开窗户呼吸新鲜空气,自然的空气是最好的。
4、在空调房里适当多喝白开水。可用金银花、菊花、生地等煮水当茶饮用,清热解毒。
开空调后房间墙壁潮湿有水珠2
室内冷凝水主要是由室内和室外之间的温差大引起的,通常在冬天发生。 当室内温度和湿度较高而室外温度较低时,或当保温环境较差且空气不流通时,当冷空气进入室内时,冷凝水很容易出现。 那么,冬季内壁的冷凝水如何破裂? 如果条件允许,您可以在室内重新制作绝缘层以增强绝缘效果。 或者尝试尽量减少进入房间的冷空气,如果早晨和傍晚之间的温差较大,请记住要关闭窗户。
墙上返潮都是水珠咋办
农村墙面返潮主要是墙壁较薄,不保温,导致屋外凉屋内上霜变水珠。第二是室内温度太低。第三是屋顶透风不保温。一般都是后面墙较重。解决办法,一是用一些玉米秸把后墙围起来保暖,二是增加室内温度,在就是屋顶增加保温层。
房屋地面潮湿经常有水珠怎么办
地面的防水没有做好。
空气湿度大的时候,如果地面墙壁比较凉的话,就会渗出水珠。
如果可以的话,最好能做一层防水之后再装修。刷防水胶也可以对付,要不就关闭门窗后使用除湿机或开空调的除湿功能。
在知道墙壁在哪里的同时计算房间
【中文标题】在知道墙壁在哪里的同时计算房间【英文标题】:Counting Rooms While Knowing Where Walls Are 【发布时间】:2016-10-18 11:23:15 【问题描述】:这个问题是关于 C++ builder 6 的代码。赏金有兴趣使用标准 C++ 算法来解决给定标准化输入的问题(有关更多信息,请参阅this。)
txt 文件也代表我在数组中的数据:
1101 0110 1101 0110 1100 0101 0110 1110 1001 0110 1011 1010 1111 1010 1000 0101 0011 1110 1011 1110 1010 1011 1101 0101 0001 0101 0011 1011
txt的解释: txt 文件中的数字是房间墙壁的 4 位表示,设置位表示墙壁。墙位按顺时针顺序排列,最重要的位是西墙。例如,1101 代表一个房间,其中:
最高有效位置的设置位表示西边的墙 下一个最高有效位置的设置位表示北面是一堵墙 未设置的位表示东边没有墙 最低有效位置的设置位表示南面的墙鉴于:
-
房间的外墙总是有一堵墙
内墙将始终在两个房间中表示(在示例中,因为 (1, 1) 的房间是 1101 它包含南面的墙,位于 (1, 2) 的房间1110 必须在北边有一堵墙
永远不会超过
numeric_limits<int>::max()
个房间
我是was asked to post my code 所以这里是: 我已尝试解决此问题,但遇到 EAAccessviolation 有人可以告诉我我做错了什么吗?
int rn=0,z=0, global=0,coord[15],c[411],b1[411];
void peruse ( int i, int j,int* bb)
bool top=false,bottom=false,right=false,left=false;
//truth checks
if (bb[i*m+j]<1000) left=true;
if (bb[i*m+j]<100) top=true; else if (bb[i*m+j]-1000<100) top=true;
if (bb[i*m+j]<10) right=true; else
if ( (bb[i*m+j]-100<10) || (bb[i*m+j]-1000<10) || (bb[i*m+j]-100<10) ) right=true;
if (bb[i*m+j]<1) bottom=true; else
if ( (bb[i*m+j]-10<1) || (bb[i*m+j]-100<1) || (bb[i*m+j]-1000<1) ||(bb[i*m+j]-100<1))
bottom=true;
//marc
if (left)
c[i*m+j]=c[i*m+j]+1000; // EAaccessViolation i dont know why.....
peruse(i,j-1,c);
if (top)
c[i*m+j]=c[i*m+j]+100;
peruse(i-1,j,c);
if (right)
c[i*m+j]=c[i*m+j]+10;
peruse(i,j+1,c);
if (bottom)
c[i*m+j]=c[i*m+j]+1;
peruse(i+1,i,c);
if ( !(left) && !(top) && !(right) && !(bottom) )
bb[411]++;
void __fastcall TForm1::Button7Click(TObject *Sender)
b1[411]=0;
for(int i=0;i<n;i++)
for (int j=0;j<m;j++)
b1[i*m+j]=b[i][j];
c[i*m+j]=b[i][j];
peruse (1,1,b1);
ShowMessage("Nr. "+IntToStr(b1[411]) );
【问题讨论】:
"请把代码写给我" 请给我一个想法,或者如果可能的话,给我一个例子。谢谢。 @JonathanMee 我明白了。看到尼基塔琼恩在说什么了吗?您有机会尝试并在此处发布“您的代码”以及您的为什么和何时失败了,你期待什么,我们会帮助你。如果你自己不做,没有人会为你做 好的,我会尝试检查零,直到它击中一个并将这些零转换为零,但它是一种更多用于海战的算法,所以我不确定它是否可以在这里工作。谢谢。 @NikitaCebotari 您应该阅读有关不相交集数据结构的信息。这可能会有所帮助。 【参考方案1】:老实说,我真的很想尝试解决这个问题。所以我要说你已经在这方面做出了勇敢的努力,然后继续向你展示如何去做。我将假设您可以提供以下算法:
-
以二进制读取的输入数字(因此“1101”将被读取为十进制数“13”)
const vector<char> rooms
中的所有这些数字
每行“房间”的宽度可以输入size_t width
(必须在所有行中保持一致,我们必须使用矩形房间)
“房间”的所有外部“墙”都会有“墙”
少于numeric_limits<int>::max()
“房间”
我们将使用vector<int> temp
标记每个房间,我们将构造它的大小为rooms
并将每个标签初始化为0。int result
将用于标记房间,并将初始化为0 . 但是因为替换较小的标签时不会减少所有房间标签,所以size(set<int>(cbegin(temp), cend(temp)))
将用于查找最终的标签计数。
我们的解决方案将围绕一个功能构建,该功能包含两个没有墙壁的“房间”;这样:
-
一个房间尚未标记,在这种情况下,它将采用另一个房间的标签
两个房间共享一个标签,在这种情况下不会发生任何操作
一个房间标签较小,在这种情况下,较大标签的所有房间都将分配较小的标签
关于此函数的重要说明,我使用一元加号运算符从 L 值 int&
构造 R 值 int
更多信息 here。更清晰的解决方案可能是使用static_cast<int>
,但由于某种原因,Visual Studio 2015 无法按预期工作更多信息here。
void generate(vector<int>& temp, int& target, const size_t width, const size_t i)
const auto replacement = temp[i];
if (target > replacement)
replace(begin(temp), next(begin(temp), min(size(temp), i + width - 1)), target, replacement);
else
target = replacement;
使用此代码,我们能够:
for (size_t i = 0U; i < size(rooms); ++i)
const auto toWest = (rooms[i] & 0b1000) == 0;
const auto toNorth = (rooms[i] & 0b100) == 0;
const auto toEast = (rooms[i] & 0b10) == 0;
const auto toSouth = (rooms[i] & 0b1) == 0;
const auto west = toWest && temp[i - 1] != 0 ? temp[i - 1] : numeric_limits<int>::max();
const auto north = toNorth && temp[i - width] != 0 ? temp[i - width] : numeric_limits<int>::max();
const auto east = toEast && temp[i + 1] != 0 ? temp[i + 1] : numeric_limits<int>::max();
temp[i] = min( temp[i] != 0 ? temp[i] : numeric_limits<int>::max(), result + 1, west, north, east );
if (temp[i] == result + 1) ++result;
if (toWest) generate(temp, temp[i - 1], width, i);
if (toNorth) generate(temp, temp[i - width], width, i);
if (toEast) generate(temp, temp[i + 1], width, i);
if (toSouth) temp[i + width] = temp[i];
Live Example
【讨论】:
【参考方案2】:这是一个在图中求connected components总数的典型问题。
让我通过关注以下几点来帮助您形象化类比,请记住我们在这里处理的是undirected graphs。
1。在图中,我们有各种顶点,如果两个顶点之间有边,则称它们彼此相邻。 就像你的城堡一样,如果一个单元可以通向另一个单元,那么两个单元彼此相邻。
2。在一个图中,如果两个顶点之间有一条使用边的路径,那么我们有两个顶点属于同一个连通分量。 就像你的城堡一样,两个牢房属于同一个房间号,如果一个牢房可以通过一条牢房的路径通向另一个。
3。在图中,我们有连接组件,因此连接组件由顶点组成,因此连接组件的每两个顶点之间都有一条路径。就像我们有房间的城堡一样,每两个单元格同一个房间之间有一条细胞路径。
现在,如果您仍然想知道如何构建图表,那么这很容易。
顶点的数量将是NxM
(对于大小为 N 行 M 列的城堡),它等于单元的数量。
只需按顺序对单元格编号,如果两个单元格相邻,cell a(meaning vertex a)
和 cell b(vertex b)
之间就有一条边。
现在可以通过在您构建的图表上应用 bfs 或 dfs 算法轻松计算房间总数。
算法在我提供的第一个链接中描述。
【讨论】:
您的回答非常有道理,但我的大脑无法理解我将如何准确地根据我以前从未见过的图表制作图表。谢谢。 @NikitaCebotari 我只是无法用一个答案来解释数据结构图。***和 youtube 是一个不错的起点。 @NikitaCebotari 你现在学习它们也很好,因为它们是大多数问题的组成部分,可以使用算法轻松解决。【参考方案3】:一种简单的方法是创建一个具有房间大小的数组并用“0”初始化它。 之后,您应该遍历数组。如果找到“0”,则从该点开始 BFS,并将数组结果着色为当前数字。
关于 BFS 的信息
BFS 必须查看直接邻居并检查此数组内是否有“0”。如果这是真的,BFS 必须检查两个盒子之间是否没有墙。如果中间没有墙,则使用当前颜色(开头为 1)为该框着色,并在新框上调用 BFS。
当房间完全着色时,BFS 会自动停止。然后全局颜色将增加 1,循环继续并寻找下一个“0”。
在循环之后,房间的数量存储在全局颜色值中。
这个算法在 O(n) 中工作
小例子:
//CountingRooms.h
#include <vector>
class CountingRooms
public:
CountingRooms();
~CountingRooms();
int Count();
void TestFill();
void Print();
private:
struct Point
int x = 0;
int y = 0;
;
unsigned int* m_arrFieldColors = nullptr;
unsigned int* m_arrFieldWalls = nullptr;
int m_nSizeX = 0;
int m_nSizeY = 0;
int m_nCurrentColor = 0;
unsigned int GetValue(unsigned int* field, int x, int y);
void SetValue(unsigned int* field, int x, int y, unsigned int value);
bool CanPass(int x1, int y1, int x2, int y2);
void DFS(int posX, int posY);
bool IsInsideArray(int x1, int y1);
;
//CountingRooms.cpp
#include "stdafx.h"
#include "CountingRooms.h"
#include <iostream>
CountingRooms::CountingRooms()
CountingRooms::~CountingRooms()
if (m_arrFieldColors)
delete[]m_arrFieldColors;
if (m_arrFieldWalls)
delete[]m_arrFieldWalls;
bool CountingRooms::IsInsideArray(int x, int y)
return x >= 0 && y >= 0 && x < m_nSizeX && y < m_nSizeY;
bool CountingRooms::CanPass(int x1, int y1, int x2, int y2)
if (IsInsideArray(x1, y1) && IsInsideArray(x2, y2)) //inside the array range
if (x2 - x1 == 1 && y2 - y1 == 0) // right
if (!(GetValue(m_arrFieldWalls, x1, y1) & 2) && !(GetValue(m_arrFieldWalls, x2, y2) & 8)) return true;
if (x2 - x1 == 0 && y2 - y1 == -1) // up
if (!(GetValue(m_arrFieldWalls, x1, y1) & 4) && !(GetValue(m_arrFieldWalls, x2, y2) & 1)) return true;
if (x2 - x1 == -1 && y2 - y1 == 0) // left
if (!(GetValue(m_arrFieldWalls, x1, y1) & 8) && !(GetValue(m_arrFieldWalls, x2, y2) & 2)) return true;
if (x2 - x1 == 0 && y2 - y1 == 1) // down
if (!(GetValue(m_arrFieldWalls, x1, y1) & 1) && !(GetValue(m_arrFieldWalls, x2, y2) & 4)) return true;
return false;
void CountingRooms::DFS(int posX, int posY)
if (GetValue(m_arrFieldColors, posX, posY)) // check if the field is already colored
return;
Point sStart;
sStart.x = posX;
sStart.y = posY;
std::vector<Point> vecList;
vecList.push_back(sStart);
m_nCurrentColor++;
while (vecList.size()) // as long as something is inside the list
Point sTemp = vecList[vecList.size()-1]; //get out the last element
vecList.pop_back();
if (IsInsideArray(sTemp.x, sTemp.y))
if (!GetValue(m_arrFieldColors, sTemp.x, sTemp.y)) // is field not colored
SetValue(m_arrFieldColors, sTemp.x, sTemp.y, m_nCurrentColor);
if (CanPass(sTemp.x, sTemp.y, sTemp.x + 1, sTemp.y)) /* right*/
Point newPoint;
newPoint.x = sTemp.x + 1;
newPoint.y = sTemp.y;
vecList.push_back(newPoint);
if (CanPass(sTemp.x, sTemp.y, sTemp.x - 1, sTemp.y)) /* left*/
Point newPoint;
newPoint.x = sTemp.x - 1;
newPoint.y = sTemp.y;
vecList.push_back(newPoint);
if (CanPass(sTemp.x, sTemp.y, sTemp.x, sTemp.y - 1)) /* up*/
Point newPoint;
newPoint.x = sTemp.x;
newPoint.y = sTemp.y - 1;
vecList.push_back(newPoint);
if (CanPass(sTemp.x, sTemp.y, sTemp.x, sTemp.y + 1)) /* down*/
Point newPoint;
newPoint.x = sTemp.x;
newPoint.y = sTemp.y + 1;
vecList.push_back(newPoint);
int CountingRooms::Count()
m_nCurrentColor = 0;
for (int i = 0; i < m_nSizeY; ++i)
for (int j = 0; j < m_nSizeX; ++j)
DFS(j, i);
return m_nCurrentColor;
void CountingRooms::TestFill()
m_arrFieldWalls = new unsigned int[42]13, 6,13, 6,12, 5, 6,
14, 9, 6,11,10,15,10,
8, 5, 3,14,11,14,10,
11,13, 5, 1, 5, 3,11;
m_arrFieldColors = new unsigned int[42];
for (int i = 0; i < 42;i++)
m_arrFieldColors[i] = 0;
m_nSizeX = 7;
m_nSizeY = 4;
unsigned int CountingRooms::GetValue(unsigned int* field, int x, int y)
if (IsInsideArray(x, y))
return field[x + m_nSizeX*y];
return -1;
void CountingRooms::SetValue(unsigned int* field, int x, int y, unsigned int value)
if (IsInsideArray(x, y))
field[x + m_nSizeX*y] = value;
void CountingRooms::Print()
std::cout << "Walls:" << std::endl;
for (int j = 0; j < m_nSizeY;++j)
for (int i = 0; i < m_nSizeX;++i)
std::cout << GetValue(m_arrFieldWalls, i, j) << "\t";
std::cout << std::endl;
std::cout << std::endl<<"Colors:" << std::endl;
for (int j = 0; j < m_nSizeY;++j)
for (int i = 0; i < m_nSizeX;++i)
std::cout << GetValue(m_arrFieldColors, i, j) << "\t";
std::cout << std::endl;
//main.cpp
#include "stdafx.h"
#include <iostream>
#include "CountingRooms.h"
int main()
CountingRooms cr;
cr.TestFill();
std::cout<<"There are "<<cr.Count()<<" rooms"<<std::endl;
cr.Print();
char key = 0;
std::cin >> key;
return 0;
顺便说一句:BFS 被 DFS 取代,但两者都在工作。
输出
【讨论】:
它不是一个简单的 BFS 算法的原因是我们经常需要重新着色房间。考虑输入集:const vector<char> rooms = 0b1110, 0b1110, 0b1001, 0b0011
和 const size_t width = 2U
在这种情况下,第二个房间最初将使用与第一个房间不同的颜色着色,但随后应使用与第一个房间相同的颜色重新着色。我认为在 O(n) 中没有办法做到这一点,但我希望看到实际的编码尝试!
嘿,我很感激在这方面的努力......我很遗憾看到你和我似乎是唯一对这个问题感兴趣的人。因此,如果你能获得解决问题的代码(如果你能击败我的运行时,我会很乐意给你至少一个 +1有大量的云编译器可供您使用。随意 fork my code 并比较我们的输出。
我 100% 确定,这个想法还在工作。也许有一些sintax错误,但它们应该很容易修复。唯一要做的就是将这些位放入一个整数数组并运行此代码。
是的,您的代码中肯定存在语法问题。但在大多数情况下,它们看起来很简单,所以我同意它们不应该很难修复。我认为最简单的方法是分叉my code 并进行比较。但是,如果您遇到问题,您可以随时访问ideone.com 并从头开始。
@JonathanMee 抱歉,我现在在上班……我回家后会这样做【参考方案4】:
您的代码很少有问题禁止从第三方进行正确调试,例如有关其工作原理的信息不足,未定义的变量 (m,n,b
) 数组溢出(大量访问 [411]
而大小仅为 411
而不是412
) 从一开始就阻止任何人尝试(让人怀疑代码是否真的有用并且值得花时间花时间)。我也很好奇,所以我在 BDS2006 Turbo C++(BCB6 的继任者,所以这段代码也应该在那里工作)中为这个任务做了简单的未优化尝试。
[rooms.h]
//---------------------------------------------------------------------------
#ifndef _rooms_h
#define _rooms_h
//---------------------------------------------------------------------------
class rooms
public:
// variables
int xs,ys; // map resolution
DWORD **map; // map[xs][ys]
enum
_W=8,
_N=4,
_E=2,
_S=1
;
// internals
rooms();
~rooms();
void _free(); // release map memory
// inteface
void resize(int _xs,int _ys); // realloc map to new resolution
void set(AnsiString txt); // copy txt to map
void draw(TCanvas *scr,int x,int y,int sz); // draw map on Canvas at (x,y) with grid size sz
int count(); // count rooms
;
//---------------------------------------------------------------------------
rooms::rooms() map=NULL; xs=0; ys=0;
rooms::~rooms() _free();
//---------------------------------------------------------------------------
void rooms::_free()
if (map)
for (int x=0;x<xs;x++)
if (map[x])
delete[] map[x];
delete[] map;
map=NULL; xs=0; ys=0;
//---------------------------------------------------------------------------
void rooms::resize(int _xs,int _ys)
if ((xs==_xs)&&(ys==_ys)) return;
_free();
xs=_xs; ys=_ys;
map=new DWORD*[xs];
for (int x=0;x<xs;x++)
map[x]=new DWORD[ys];
//---------------------------------------------------------------------------
void rooms::set(AnsiString txt)
int i,l,x,y,n0,n1;
l=txt.Length(); if (!l) return;
// count eof lines (ys)
for (y=0,i=1;i<=l;i++)
if ((txt[i]==13)||(txt[i]==10))
y++;
if (i<l)
if ((txt[i+1]==13)||(txt[i+1]==10)) i++;
if ((txt[l]!=13)&&(txt[l]!=10)) y++; // handle missing last eof
// count numbers per line (xs)
for (n1=0,x=0,i=1;i<=l;i++)
n0=n1; n1=0;
if ((txt[i]=='0')||(txt[i]=='1')) n1=1;
if ((txt[i+1]==13)||(txt[i+1]==10)) break;
if ((!n0)&&(n1)) x++;
// copy data
resize(x,y);
for (x=0,y=0,i=1;i<=l;)
// skip spaces
while ((i<=l)&&(txt[i]!='0')&&(txt[i]!='1')) i++;
// read 4 bit bin number
n0= 0; if (i>l) break; if (txt[i]=='1') n0|=1; i++;
n0<<=1; if (i>l) break; if (txt[i]=='1') n0|=1; i++;
n0<<=1; if (i>l) break; if (txt[i]=='1') n0|=1; i++;
n0<<=1; if (i>l) break; if (txt[i]=='1') n0|=1; i++;
map[x][y]=n0;
x++; if (x>=xs) x=0; y++; if (y>=ys) break;
// clear the rest in case of error in data
if ((y<ys)&&(x<xs)) for (;;)
map[x][y]=0;
x++; if (x>=xs) x=0; y++; if (y>=ys) break;
//---------------------------------------------------------------------------
void rooms::draw(TCanvas *scr,int x0,int y0,int sz)
int x,y,xx,yy;
DWORD a;
scr->Brush->Color=clDkGray;
scr->Brush->Style=bsSolid;
scr->FillRect(Rect(x0,y0,x0+xs*sz,y0+ys*sz));
scr->Pen->Color=clBlue;
scr->Pen->Width=5;
scr->Font->Color=clBlack;
scr->Brush->Style=bsClear;
for (xx=x0,x=0;x<xs;x++,xx+=sz)
for (yy=y0,y=0;y<ys;y++,yy+=sz)
a=map[x][y]&15;
if (DWORD(a&_W)) scr->MoveTo(xx ,yy ); scr->LineTo(xx ,yy+sz);
if (DWORD(a&_N)) scr->MoveTo(xx ,yy ); scr->LineTo(xx+sz,yy );
if (DWORD(a&_E)) scr->MoveTo(xx+sz,yy ); scr->LineTo(xx+sz,yy+sz);
if (DWORD(a&_S)) scr->MoveTo(xx ,yy+sz); scr->LineTo(xx+sz,yy+sz);
scr->TextOutA(xx+(sz>>1),yy+(sz>>1),map[x][y]>>4);
scr->Brush->Style=bsSolid;
scr->Pen->Width=1;
//---------------------------------------------------------------------------
int rooms::count()
int x,y,i,i0,i1,w0,w1,n,e;
// each block is a separate room
for (n=0,x=0;x<xs;x++)
for (y=0;y<ys;y++,n+=16)
map[x][y]&= 0x0000000F; // low 4 bits are walls
map[x][y]|=n&0xFFFFFFF0; // rest is room index
n>>=4;
// reindex all indexes i0 to i1
#define map_reindex(i0,i1) \
for (x=0;x<xs;x++) \
for (y=0;y<ys;y++) \
if (DWORD(map[x][y]&0xFFFFFFF0)==i0) \
\
map[x][y]&= 0x0000000F; \
map[x][y]|=i1&0xFFFFFFF0; \
// loop until no change has occured
for (e=1;e;)
e=0;
// merge columns
for (x=0;x<xs;x++)
for (y=1;y<ys;y++)
w0=map[x][y-1]&0x0000000F;
i0=map[x][y-1]&0xFFFFFFF0;
w1=map[x][y ]&0x0000000F;
i1=map[x][y ]&0xFFFFFFF0;
if ((i0!=i1)&&(DWORD(w0&_S)==0)&&(DWORD(w1&_N)==0)) map_reindex(i0,i1); n--; e=1;
// merge rows
for (y=0;y<ys;y++)
for (x=1;x<xs;x++)
w0=map[x-1][y]&0x0000000F;
i0=map[x-1][y]&0xFFFFFFF0;
w1=map[x ][y]&0x0000000F;
i1=map[x ][y]&0xFFFFFFF0;
if ((i0!=i1)&&(DWORD(w0&_E)==0)&&(DWORD(w1&_W)==0)) map_reindex(i0,i1); n--; e=1;
return n;
#undef map_reindex
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
[不带任何组件的单窗口VCL Form app C++源码]
//$$---- Form CPP ----
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "rooms.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
Graphics::TBitmap *bmp; // back buffer
int xs,ys; // actual window resolution
rooms map; // map of rooms
//---------------------------------------------------------------------------
void draw()
int x,y,sz;
// clear bachground
bmp->Canvas->Brush->Color=clBlack;
bmp->Canvas->Brush->Style=bsSolid;
bmp->Canvas->FillRect(Rect(0,0,xs,ys));
// compute grid size
x=(xs-20)/map.xs; sz=x;
y=(ys-20)/map.ys; if (x>y) sz=y;
// and map position so it is centered
x=(xs-(sz*map.xs))>>1;
y=(ys-(sz*map.ys))>>1;
// render to backbuffer (avoid flickering)
map.draw(bmp->Canvas,x,y,sz);
// render backbuffer to window
Form1->Canvas->Draw(0,0,bmp);
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
// init backbuffer
bmp=new Graphics::TBitmap;
bmp->HandleType=bmDIB;
bmp->PixelFormat=pf32bit;
// init map
map.set("1101 0110 1101 0110 1100 0101 0110\r\n1110 1001 0110 1011 1010 1111 1010\r\n1000 0101 0011 1110 1011 1110 1010\r\n1011 1101 0101 0001 0101 0011 1011\r\n");
Caption=map.count(); // result count is in the Window Caption
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender) delete bmp;
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender) draw();
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
// get actual window size
xs=ClientWidth;
ys=ClientHeight;
// resize backbufer and force redraw
bmp->SetSize(xs,ys);
draw();
//---------------------------------------------------------------------------
我的求解器背后的想法很简单:
ID
每个网格单元按不同的房间号
记住单元格计数为n
合并所有相邻的房间,它们之间没有任何墙
所以循环遍历所有房间,如果任何相邻的单元格没有墙壁并且有不同的房间ID
重新索引其房间号,以便展位房间有相同的房间。同时减少房间计数器n
。
循环 #2 直到不发生重新索引
[备注]
不要忘记在您的 IDE 中创建适当的事件,而不是仅仅复制代码,否则它将无法工作。
【讨论】:
这确实解决了问题+1。 I don't really care whether you do it in C++ builder 6 for the bounty,所以我在这里将您的代码提取到纯 C++ 文件中:ideone.com/ecd0tU 此算法似乎与我自己的解决方案相似,尽管可能是二维数组影响了您的速度。 @JonathanMee 速度被重新索引宏杀死,因为它循环遍历整个数组而不是填充或索引行合并。而且还有 3 倍的数组访问,这是真正需要的,只是为了让代码更易于理解 是的,但我的意思是我的代码中的replace
也必须经过并重新标记,但我想我只需要重新标记我已经标记的房间,而不是所有内容。所以你是对的,这可能是这里的放缓。我正在修改一个链表或类似的东西,我可以用它来将节点分配给一个标签,而不是遍历所有标签。如果加速显着,我可能会给出答案。
@JonathanMee ID 列表不是解决此问题的好方法...通过记住边界框并仅使用其区域,我得到了更好的结果...合并后您只需合并边界框,这将加快速度相当。但是对于快速图像分割,我使用线段而不是单个像素(单元格)。它将堆栈/堆垃圾和需求降低到很小的一部分...对于大分辨率,您可以递归地划分和征服地图以降低复杂性...
我再次对渲染不感兴趣。我想知道计算房间需要多长时间,IO 通常会掩盖任何计算时间,这是我感兴趣的全部。我正在测试 the extraction of that algorithm 反对我的。而那个就是我说的比我的慢。【参考方案5】:
不相交集以及Union-Find非常适合连接组件的问题。我不是使用图表,而是跟踪不同的不相交的地砖集。每个集合都有自己的代表图块,用于唯一标识该集合。
您可以阅读有关 Union-Find here 的更多信息。
算法很简单:
对于每个图块,如果没有公共墙,则处理其相邻的图块。这是使用两个图块的简单union()
完成的。当我们完成后,每个图块将属于一个不相交的集合(每个集合代表一个连接空间或房间)。附件代码中parent[]
存放了代表元素。
计算唯一代表元素的数量。这是不相交集的数量(因此是连接空间或房间的数量)。
一些额外的观察:
在任何时候,您只需要处理北墙和西墙。 (为什么?证明留给读者。)
那是因为对于一个瓷砖
a[i][j]
,它的南墙和东墙可以分别被瓷砖a[i+1][j]
和a[i][j+1]
处理。
为什么我们需要标准化每个图块的代表?原因是某些集合最终可能包含两个或多个具有代表性的元素。我们递归地找到父元素以获得整个集合的唯一代表。 (如果您想对此进行测试,请从附加代码中注释掉以下行:
// normalise each tile
parent[i] = findSet(parent[i]);
所附代码使用了一个特殊版本的 Union-Find,有两个启发式:
rank 联合(由ranks[]
证明)
路径压缩
附上代码:Live Example
【讨论】:
以上是关于开空调后房间墙壁潮湿有水珠的主要内容,如果未能解决你的问题,请参考以下文章