あるごりの復習。〜〇〇優先〜
何もなければ1日に1問。時に2問
まぁ知っていないと困りそうだんぁ〜っていう焦りからですね。
なんとなく、デイリーなワークとしてはじめて見るよ。
ちなみに、ブルゾンの"dirty work"を"daily work"と思っている人がいるらしい。
MV見れば全く"daily"じゃないのに。。。
んで、この本をやってみるのはいいけど、続くかなぁ。基礎的な部分だけでも得られればいいんだよね1区切りついた段階でアップしていく、スタイル?多分。
あと、多分めちゃくちゃフランクに進めていくし、若干本家と違うかもだけど、
あくまで自分が理解できていればいいスタンスなので!
ぶっちゃけ、遊びたい
まぁ遊ぶけど、一人酒に慣れてきて、、、まだ学生だぜ。。。
それでは、
DFS(depth first search)
深さ優先探索ってやつ。昔やった。
要は、あるポイントを見つける。
その状態から繊維できなくなる状態までいってみる
限界迎えたら、1つ前に戻ってみる。
ってことを繰り返して探索するんだけど、つまり再帰関数が得意とする探索で。暗に、スタック(先入れ後出し)を意味しているらしい。へぇ。
計算量O(2^N)。メモリ使用量は再帰関数の深さに比例する。(深く潜る分だけ、浅いところを待たせている。)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
//部分話をとく問題 //整数a1~an がgiven (n個) //いくつか選んで、合計kにできるか #include <cstdio> int
a[7]
=
{1,5,8,3,6,4,3}
; int
n
=
3; int
k
=
7; //深さ優先木を作る //i : 深さ(配列長とみなせる),sum : //n : 最大深度 bool
dfs(int
i,
int
sum){
//最大深度に到達したら、その地点での合計とkを比較
if(i
==
n)
return
sum
==
k;
//**最大深度でない場合に次の深度へ
//深度iを使う場合に分岐(分岐先でtrueならこれもtrue,そうでないなら<*>)
if(dfs(i+1,sum))
return
true;
//深度iを使わない場合に分岐(分岐先でtrueならこれもtrue,そうでないなら<*>)
if(dfs(i+1,sum+a[i]))
return
true;
//<*>そうでない場合
return
false; } void
solve(){
if
(dfs(0,0))
printf("Yes\n");
else
printf("No\n"); } int
main(){
solve(); } |
んで、もう一個あった。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
//大きさN*Mの庭にの中に水たまりを設定 //8近傍に水たまりがあれば、連結とみなし //何個水たまりが存在するか? #include <stdio.h> #include <time.h> #include <stdlib.h> //庭の大きさ const
int
N
=
10; const
int
M
=
10; char
field[N][M]; //水たまりのランダム作成 void
set_input(){
const
char
str[]
=
"W.";
//水:w、土:.
srand((unsigned
int)time(NULL));
for(int
i
=
0;
i
<
N;
i++){
for(int
j
=
0;
j
<
M;
j++){
field[i][j]
=
str[rand()%2];
printf("%c",field[i][j]);
}
printf("\n");
}
printf("\n");
return; } //現在状況出力 void
out_put(){
for(int
i
=
0;
i
<
N;
i++){
for(int
j
=
0;
j
<
M;
j++){
printf("%c",field[i][j]);
}
printf("\n");
}
printf("\n");
return; } //深さ優先木2 //あるポイント(i,j)から手繰れるポイントまで到達してみる。 void
dfs(int
i,int
j){
//水を土にしていく(到達ポイントは目印として、”.”にする)
field[i][j]
=
'.';
//(i,j)から8方向に深掘りする
for(int
tmp_i
=
i-1;
tmp_i
<=
i
+
1;
tmp_i++){
for(int
tmp_j
=
j-1;
tmp_j
<=
j
+
1;
tmp_j++){
//庭の範囲内確認
if(tmp_j
>=
0
&&
tmp_j
>=
0
&&
tmp_i
<=
N
&&
tmp_j
<=
M){
if(field[tmp_i][tmp_j]
==
'W'){
//さらに手繰れる場合は次の深度へ
dfs(
tmp_i
,
tmp_j
);
}
}
}
}
return; } //深さ優先木1 //深さ:座標になる。 void
solve(){
int
ans
=
0;
for(int
n
=
0;
n
<
N;
n++){
for(int
m
=
0;
m
<
M;
m++){
//水ポイントを発見
if(field[n][m]
==
'W'){
ans++;
dfs(n,m);
//そこからできる範囲で土にしていく(深さ優先)
out_put();
//次なる水ポイントを発見する。
}
}
}
printf("%d\n",ans);
return; } int
main(){
set_input();
solve(); } |
今日はここまでだわ。疲れた。







