題目:小z的房子
高級語言程序設計實踐題目:2.4 小z 的房子
★實驗任務
小z 通過自己的努力,終於發家致富。現在小明有一個大小爲N*M 的
院子,雨後積起了水。四聯通的積水被認爲是連接在一起的。請你幫
小z 計算出院子裏有多少水窪。1 代表積水,0 代表沒有積水。(四
聯通指下面圖中下對1 的部分)
*
*1*
*
★數據輸入
輸入數據共兩行。
第一行爲一個整數N,M(1<=N,M<=100)表示院子的大小。
接下來N 行M 列的矩陣表示院子中積水情況。
★數據輸出
輸出數據共一行,爲水窪個數。
輸入示例輸出示例
5 5
00001
01101
01001
11101
11001
2
HINT:
可以百度學習下深度優先搜索。
代碼:
#include<stdio.h>
#include<stack>
using namespace std;
char a[105][105];
struct pla
{
int x,y;
};
int tran[5][3]={{-1,0},{1,0},{0,-1},{0,1}};
int n,m;
void DFS(int i,int j)
{
pla begin,between;
begin.x=i;
begin.y=j;
stack<pla>s;
s.push(begin);
a[begin.x][begin.y]='0';//turn 0;
while(!s.empty())
{
begin=s.top();
s.pop();
for(i=0;i<4;i++)
{
between.x=begin.x+tran[i][0];
between.y=begin.y+tran[i][1];
if(between.x>0 && between.x<=n && between.y>0 && between.y<=m && a[between.x][between.y]=='1')
{
//printf("1\n");
s.push(between);
a[between.x][between.y]='0';
}
}
}
}
int main()
{
int i,j,k,t=0,sum=0;
scanf("%d%d",&n,&m);
getchar();
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%c",&a[i][j]);
}
getchar();
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(a[i][j]=='1')
{
DFS(i,j);
//printf("%d %d\n",i,j);
sum++;
}
}
}
/*for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
printf("%c",a[i][j]);
printf("\n");
}*/
printf("%d",sum);
return 0;
}
注意:這裏的四聯通指的是上下左右。
關於深度優先搜索,可以參考我的blog:深度優先搜索初嘗試
在理解完深度優先搜索以後相信此題不是什麼難事。
練習:
題目:驗證碼識別(abc.cpp/c/pas)
【題目描述】
很久很久以前,百度貼吧的爆吧軍團藉助着爆吧機器和大批人手在各個貼吧裏面替天行道!後來百度放出了養了很久的超級驗證碼,爆吧的效率便低了很多,爆吧軍團從此一蹶不振。機智的Kiana,最近加入了沉寂很久的爆吧軍團風紀社!他決定想要發明一個驗證碼識別器,重整風紀社的雄姿!
爲了簡化問題,我們的驗證碼爲“A”,“B”,“C”字母中的一個,被畫在一個n*m的矩陣中,0表示白色,1表示黑色(題目保證驗證碼是黑色的>_<,並且字母和邊界不會相連0.0)。。但是由於百度君的喪心病狂,驗證碼是標準字體被進行了無數次的拉伸,縮放,旋轉,壓縮,翻轉的操作,有可能會變得難以辨認。而作爲Oier的你就是要編寫一個程序辨認驗證碼。
【輸入格式】
第1行:兩個整數n、m,表示矩陣大小爲n行m列
第2..n+1行:每行m個整數,0表示此點爲白色,1表示此點爲黑色。
【輸出格式】
輸出識別出來的驗證碼,爲“A”,“B”,“C”中的一個。
【樣例輸入】
7 7
0 0 0 0 0 0 0
0 0 0 1 0 0 0
0 0 1 0 1 0 0
0 0 1 1 1 0 0
0 0 1 0 1 0 0
0 0 1 0 1 0 0
0 0 0 0 0 0 0
【樣例輸出】
A
【樣例解釋】
【數據範圍】
10%的數據保證1<=n,m<=10且爲標準的字體【就像樣例一樣的好看的字體喲!】
30%的數據保證1<=n,m<=100且字體並不是那麼喪心病狂!
100%的數據保證1<=n,m<=1000