BOJ 1194月がいっぱいになるから、行きましょう.
質問リンク
https://www.acmicpc.net/problem/1194
質問する
に答える
これはBFS+ビットシールドの問題です.
問題の核心は次のとおりです.
1.ビットマスクを使用してキーがあるかどうかを確認する
鍵を携帯するかどうかはアクセスできるかどうかによって決まるので、ビットマスクで鍵を携帯するかどうかをチェックしました.
ex 1)鍵の取得
現在aキーとdキーを持っていると仮定し、次のアクセス領域にキーfがある場合は、ビット演算(|)でキーを取得できます.
key : fedcba
now : 001001 (9) f : 100000 (32)
===============
101001 (41)
すなわち、now=now|fで鍵を得ることができる.
鍵があるかどうか
cキーとdキーを持ち、次のアクセス領域に文Cがあると仮定すると、ビット演算(&)でアクセス可能かどうかを確認できます.
key : fedcba
now : 001100 ( 12 )
C : 000100 ( 4 )
===============
000100
つまり、key&C=Cがtrueの場合は、
2.アクセススケジュールでアクセスするかどうかをチェック
アクセス状況だけでなく、どのキーを使用してアクセスする場所もチェックします.△BOJ 206壁を破壊し移動する問を似たようなタイプで解くと役に立ちます.
鍵の種類はa~fの6種類なので6桁使います.
したがって、最大値は2^6−1=63であるため、配列はvisit[51][51][64]と宣言し、アクセスするかどうかを示す.
コード#コード# #include <iostream>
#include <queue>
using namespace std;
typedef struct pos {
int x, y, key;
};
int n, m;
int days;
char maps[51][51];
bool vi[51][51][64];
int dx[4]{ 0,0,1,-1 };
int dy[4]{ 1,-1,0,0 };
queue<pos> q;
int bfs() {
while (!q.empty()) {
int sz = q.size();
for (int i = 0; i < sz; i++) {
int x = q.front().x;
int y = q.front().y;
int key = q.front().key;
q.pop();
for (int j = 0; j < 4; j++) {
int nx = x + dx[j];
int ny = y + dy[j];
if (nx < 0 || nx >= n || ny < 0 || ny >= m ) continue;
if (maps[nx][ny] == '.') {
if (!vi[nx][ny][key]) {
vi[nx][ny][key] = true;
q.push({ nx,ny,key });
}
}
else if ('a' <= maps[nx][ny] && maps[nx][ny] <= 'f') {
int temp_key = 1;
temp_key <<= (maps[nx][ny] - 'a');
int nkey = key | temp_key;
if (!vi[nx][ny][nkey]) {
vi[nx][ny][nkey] = true;
q.push({ nx,ny,nkey });
}
}
else if ('A' <= maps[nx][ny] && maps[nx][ny] <= 'F') {
int temp_key = 1;
temp_key <<= (maps[nx][ny] - 'A');
if ( ( (temp_key & key) == temp_key ) && !vi[nx][ny][key]) {
vi[nx][ny][key] = true;
q.push({ nx,ny,key });
}//열쇠 있는 경우
}
else if(maps[nx][ny]=='1'){
return days+1;
}
}//for j
}//for i
days++;
}//while(!q.empty())
return -1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> maps[i][j];
if (maps[i][j] == '0') {
vi[i][j][0] = true;
maps[i][j] = '.';
q.push({ i,j,0 });
}
}
}
cout << bfs();
}
ポスト
ビットマスクの概念をよく把握している問題だと思います.
BeatMaskingの問題を解決した経験はありませんが、いい練習でした.
Reference
この問題について(BOJ 1194月がいっぱいになるから、行きましょう.), 我々は、より多くの情報をここで見つけました
https://velog.io/@bgg01578/달이-차오른다-가자
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
に答える
これはBFS+ビットシールドの問題です.
問題の核心は次のとおりです.
1.ビットマスクを使用してキーがあるかどうかを確認する
鍵を携帯するかどうかはアクセスできるかどうかによって決まるので、ビットマスクで鍵を携帯するかどうかをチェックしました.
ex 1)鍵の取得
現在aキーとdキーを持っていると仮定し、次のアクセス領域にキーfがある場合は、ビット演算(|)でキーを取得できます.
key : fedcba
now : 001001 (9) f : 100000 (32)
===============
101001 (41)
すなわち、now=now|fで鍵を得ることができる.
鍵があるかどうか
cキーとdキーを持ち、次のアクセス領域に文Cがあると仮定すると、ビット演算(&)でアクセス可能かどうかを確認できます.
key : fedcba
now : 001100 ( 12 )
C : 000100 ( 4 )
===============
000100
つまり、key&C=Cがtrueの場合は、
2.アクセススケジュールでアクセスするかどうかをチェック
アクセス状況だけでなく、どのキーを使用してアクセスする場所もチェックします.△BOJ 206壁を破壊し移動する問を似たようなタイプで解くと役に立ちます.
鍵の種類はa~fの6種類なので6桁使います.
したがって、最大値は2^6−1=63であるため、配列はvisit[51][51][64]と宣言し、アクセスするかどうかを示す.
コード#コード# #include <iostream>
#include <queue>
using namespace std;
typedef struct pos {
int x, y, key;
};
int n, m;
int days;
char maps[51][51];
bool vi[51][51][64];
int dx[4]{ 0,0,1,-1 };
int dy[4]{ 1,-1,0,0 };
queue<pos> q;
int bfs() {
while (!q.empty()) {
int sz = q.size();
for (int i = 0; i < sz; i++) {
int x = q.front().x;
int y = q.front().y;
int key = q.front().key;
q.pop();
for (int j = 0; j < 4; j++) {
int nx = x + dx[j];
int ny = y + dy[j];
if (nx < 0 || nx >= n || ny < 0 || ny >= m ) continue;
if (maps[nx][ny] == '.') {
if (!vi[nx][ny][key]) {
vi[nx][ny][key] = true;
q.push({ nx,ny,key });
}
}
else if ('a' <= maps[nx][ny] && maps[nx][ny] <= 'f') {
int temp_key = 1;
temp_key <<= (maps[nx][ny] - 'a');
int nkey = key | temp_key;
if (!vi[nx][ny][nkey]) {
vi[nx][ny][nkey] = true;
q.push({ nx,ny,nkey });
}
}
else if ('A' <= maps[nx][ny] && maps[nx][ny] <= 'F') {
int temp_key = 1;
temp_key <<= (maps[nx][ny] - 'A');
if ( ( (temp_key & key) == temp_key ) && !vi[nx][ny][key]) {
vi[nx][ny][key] = true;
q.push({ nx,ny,key });
}//열쇠 있는 경우
}
else if(maps[nx][ny]=='1'){
return days+1;
}
}//for j
}//for i
days++;
}//while(!q.empty())
return -1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> maps[i][j];
if (maps[i][j] == '0') {
vi[i][j][0] = true;
maps[i][j] = '.';
q.push({ i,j,0 });
}
}
}
cout << bfs();
}
ポスト
ビットマスクの概念をよく把握している問題だと思います.
BeatMaskingの問題を解決した経験はありませんが、いい練習でした.
Reference
この問題について(BOJ 1194月がいっぱいになるから、行きましょう.), 我々は、より多くの情報をここで見つけました
https://velog.io/@bgg01578/달이-차오른다-가자
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
#include <iostream>
#include <queue>
using namespace std;
typedef struct pos {
int x, y, key;
};
int n, m;
int days;
char maps[51][51];
bool vi[51][51][64];
int dx[4]{ 0,0,1,-1 };
int dy[4]{ 1,-1,0,0 };
queue<pos> q;
int bfs() {
while (!q.empty()) {
int sz = q.size();
for (int i = 0; i < sz; i++) {
int x = q.front().x;
int y = q.front().y;
int key = q.front().key;
q.pop();
for (int j = 0; j < 4; j++) {
int nx = x + dx[j];
int ny = y + dy[j];
if (nx < 0 || nx >= n || ny < 0 || ny >= m ) continue;
if (maps[nx][ny] == '.') {
if (!vi[nx][ny][key]) {
vi[nx][ny][key] = true;
q.push({ nx,ny,key });
}
}
else if ('a' <= maps[nx][ny] && maps[nx][ny] <= 'f') {
int temp_key = 1;
temp_key <<= (maps[nx][ny] - 'a');
int nkey = key | temp_key;
if (!vi[nx][ny][nkey]) {
vi[nx][ny][nkey] = true;
q.push({ nx,ny,nkey });
}
}
else if ('A' <= maps[nx][ny] && maps[nx][ny] <= 'F') {
int temp_key = 1;
temp_key <<= (maps[nx][ny] - 'A');
if ( ( (temp_key & key) == temp_key ) && !vi[nx][ny][key]) {
vi[nx][ny][key] = true;
q.push({ nx,ny,key });
}//열쇠 있는 경우
}
else if(maps[nx][ny]=='1'){
return days+1;
}
}//for j
}//for i
days++;
}//while(!q.empty())
return -1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> maps[i][j];
if (maps[i][j] == '0') {
vi[i][j][0] = true;
maps[i][j] = '.';
q.push({ i,j,0 });
}
}
}
cout << bfs();
}
ポスト
ビットマスクの概念をよく把握している問題だと思います.
BeatMaskingの問題を解決した経験はありませんが、いい練習でした.
Reference
この問題について(BOJ 1194月がいっぱいになるから、行きましょう.), 我々は、より多くの情報をここで見つけました
https://velog.io/@bgg01578/달이-차오른다-가자
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
Reference
この問題について(BOJ 1194月がいっぱいになるから、行きましょう.), 我々は、より多くの情報をここで見つけました https://velog.io/@bgg01578/달이-차오른다-가자テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol