HDOJ 1045 Fire Net
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 8273 Accepted Submission(s): 4753
题目描述:
一个n*n的地图,请安排blockhouse,要求在同行和同列中没有两个相互连通的blockhouse (障碍物可阻断连通)。如下图中,
第一张图是没有安排blockhouse的图,图中只有墙(wall)
第二和第三张图是合法的blockhouse安排方式
第四和第五张图是不合法的blockhouse安排方式
要求计算出一张图中,最大能安排多少个合法的blockhouse。
输入描述:
可重复输入。
输入一个n,表示地图大小,n≤4。
n为0时结束程序。
“.”表示空白,“X”表示墙。
输出描述:
每个案例一行,表示最大的合法的blockhouse数量。
输入样例:
4
.X..
....
XX..
....
2
XX
.X
3
.X.
X.X
.X.
3
...
.XX
.XX
4
....
....
....
....
0
输出样例:
5
1
5
2
4
我的解法:贪心
么办法最近开始学ACM,才刚刚看到贪心,百度之后发现有DFS和二分查找这两种方法。
我用贪心可是写着太蛋疼了,第一次就WA了,我还以为是算法问题。
经过和AC代码的输出比较我发现,只有当n=1且地图为“X”的时候我的答案和AC答案不一样、整个人瞬间爆炸
因为我用了sort函数:sort(bh,bh+tbh-1,CMP);
那个特例情况中tbh=0,所以末比初要小,直接GG了。
添加一个队tbh的大于0判断,直接AC!!!(— —太蛋疼了)
不过我发现用ProcessDisplay来搞算法很有趣啊,把过程可视化了。有点意思
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Point
{
int x;
int y;
};
struct Blockhouse
{
Point p;
int af;
};
//ifstream input("F:\\input.txt");
//ofstream output("F:\\output.txt");
char map[4][5];
char PD[6][7];
int n,ans,
tbh,tw,//可放blockhouse总数,wall总数
tdbh;//已放blockhouse数量,
Point w[16],dbh[16];
Blockhouse bh[16];
/*
void ProcessDisplayFresh()
{
system("cls");
for(int i=0;i<tdbh;i++)
{
PD[dbh[i].x][dbh[i].y+1]='O';
}
for(int i=0;i<n;i++)
{
puts(PD[i]);
}
Sleep(400);
}
*/
int GetRowAf(Point p)
{
int a=0;
for(int j=p.y+1;j<n;j++)
if(map[p.x][j]=='.')
a++;
else
break;
for(int j=p.y-1;j>=0;j--)
if(map[p.x][j]=='.')
a++;
else
break;
return a;
}
int GetColAf(Point p)
{
int a=0;
for(int i=p.x+1;i<n;i++)
if(map[i][p.y]=='.')
a++;
else
break;
for(int i=p.x-1;i>=0;i--)
if(map[i][p.y]=='.')
a++;
else
break;
return a;
}
int isLegal(Point p)
{
for(int k=0;k<tdbh;k++)
{
if(p.x==dbh[k].x)
{
//同行
int hasWall = 0;
for(int i=0;i<tw;i++)
{
if(w[i].x==p.x && (w[i].y - p.y)*(w[i].y - dbh[k].y)<0)
hasWall = 1;
}
if(!hasWall)
return false;
}
else if(p.y==dbh[k].y)
{
//同列
int hasWall = 0;
for(int i=0;i<tw;i++)
{
if(w[i].y==p.y && (w[i].x - p.x)*(w[i].x - dbh[k].x)<0)
hasWall = 1;
}
if(!hasWall)
return false;
}
}
return true;
}
bool CMP(Blockhouse b1,Blockhouse b2)
{
return b1.af<b2.af;
}
void acm()
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(map[i][j]=='.')
{
bh[tbh].p= {i,j};
bh[tbh].af = GetColAf(bh[tbh].p) + GetRowAf(bh[tbh].p);
// printf("---------bh[%d]:(%d,%d),af=%d\n",tbh,bh[tbh].p.x,bh[tbh].p.y,bh[tbh].af);
tbh++;
}
}
}
if(tbh>0)
{
sort(bh,bh+tbh-1,CMP);
dbh[tdbh++]=bh[0].p;
// cout<<"第一个,放bh["<<0<<"]:("<<bh[0].p.x<<","<<bh[0].p.y<<")"<<endl;
for(i=1;i<tbh;i++)
{
//ProcessDisplayFresh();
// printf("尝试放入bh[%d]: (%d,%d),af=%d\n",i,bh[i].p.x,bh[i].p.y,bh[i].af);
if(isLegal(bh[i].p))
{
dbh[tdbh++]=bh[i].p;
// cout<<" 放入bh["<<i<<"]:("<<bh[i].p.x<<","<<bh[i].p.y<<")"<<endl;
// ProcessDisplayFresh();
}
}
}
ans = tdbh;
// cout<<"work:"<<n<<endl;
}
int main()
{
while(cin>>n,n>0)
{
ans=0;
tbh=0;
tw=0;
tdbh=0;
for(int i =0;i<n;i++)
{
int j;
// PD[i][0]='|';
for(j=0;j<n;j++)
{
cin>>map[i][j];
if(map[i][j]=='X')
{
w[tw++] ={i,j};
// PD[i][j+1]='X';
}
else
;
// PD[i][j+1]=' ';
}
// PD[i][j+1]='|';
// PD[i][j+2]=0;
}
//算法展示
// ProcessDisplayFresh();
//算法内容
acm();
cout<<ans<<endl;
// output<<ans<<endl;
}
}