题目传送:2815:城堡问题
AC代码(递归形式的dfs):
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define INF 0x7fffffff
using namespace std;
int n, m;
int room[55][55];
int color[55][55];
int color_num, max_room;
int tmp_room;
void dfs(int i, int j) {
if(color[i][j]) {
return;
}
color[i][j] = color_num;
tmp_room ++;
if((room[i][j] & 1) == 0) dfs(i, j - 1);//巧妙运用位运算,来判断是否有墙,且这里位运算要加上括号,因为位运算优先级较低
if((room[i][j] & 2) == 0) dfs(i - 1, j);
if((room[i][j] & 4) == 0) dfs(i, j + 1);
if((room[i][j] & 8) == 0) dfs(i + 1, j);
}
int main() {
while(scanf("%d %d", &n, &m) != EOF) {
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
scanf("%d", &room[i][j]);
}
}
color_num = 0, max_room = 0;
memset(color, 0, sizeof(color));
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
tmp_room = 0;//判断每一个连通分量(即房间)里的大小
if(color[i][j] == 0) {
color_num ++;
dfs(i, j);
max_room = max(max_room, tmp_room);//取最大值
}
}
}
printf("%d\n%d\n", color_num, max_room);
}
return 0;
}
AC代码(非递归形式的dfs):
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define INF 0x7fffffff
using namespace std;
int n, m;
int room[55][55];
int color[55][55];
int color_num, max_room;
int tmp_room;
struct Room {
int i, j;
Room(int _i, int _j) : i(_i), j(_j) {
}
};
void dfs(int i, int j) {//用stack模拟的非递归dfs
stack stk;
stk.push(Room(i,j));
while(!stk.empty()) {
Room rm = stk.top();
int p = rm.i, q = rm.j;
if(color[p][q]) stk.pop();
else {
tmp_room ++;
color[p][q] = color_num;
if((room[p][q] & 1) == 0) stk.push(Room(p, q - 1));
if((room[p][q] & 2) == 0) stk.push(Room(p - 1, q));
if((room[p][q] & 4) == 0) stk.push(Room(p, q + 1));
if((room[p][q] & 8) == 0) stk.push(Room(p + 1, q));
}
}
}
int main() {
while(scanf("%d %d", &n, &m) != EOF) {
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
scanf("%d", &room[i][j]);
}
}
color_num = 0, max_room = 0;
memset(color, 0, sizeof(color));
for(int i = 0; i < n; i ++) {
for(int j = 0; j < m; j ++) {
tmp_room = 0;//判断每一个连通分量(即房间)里的大小
if(color[i][j] == 0) {
color_num ++;
dfs(i, j);
max_room = max(max_room, tmp_room);//取最大值
}
}
}
printf("%d\n%d\n", color_num, max_room);
}
return 0;
}
题目传送:POj - 2676 - Sudoku
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define INF 0x7fffffff
using namespace std;
int mp[10][10];//代表整个图
int row_flag[10][10];//表示第i行存不存在j这个数字
int col_flag[10][10];//表示第i列存不存在j这个数字
int block_flag[10][10];//表示第i宫格存不存在j这个数字
struct Pos {//图上一个位置
int x, y;
Pos(int _x, int _y) : x(_x), y(_y) {
}
};
int get_block(int i, int j) {//获得一个位置所在的宫格
int x = (i - 1) / 3;
int y = (j - 1) / 3;
return x * 3 + y + 1;
}
void set_flag(int i, int j, int num, int f) {//为每一个位置设置标志
row_flag[i][num] = f;
col_flag[j][num] = f;
block_flag[get_block(i, j)][num] = f;
}
bool is_ok(int i, int j, int num) {
if(!row_flag[i][num] && !col_flag[j][num] && !block_flag[get_block(i, j)][num]) return true;
return false;
}
vector blank_pos;
bool dfs(int n) {
if(n < 0) return true;//递归边界
int x = blank_pos[n].x;
int y = blank_pos[n].y;
for(int i = 1; i <= 9; i ++) {
if(is_ok(x, y, i)) {
mp[x][y] = i;
set_flag(x, y, i, 1);
if(dfs(n - 1)) return true;
set_flag(x, y, i, 0);//回溯
}
}
return false;
}
int main() {
int T;
scanf("%d", &T);
while(T --) {
memset(row_flag, 0, sizeof(row_flag));
memset(col_flag, 0, sizeof(col_flag));
memset(block_flag, 0, sizeof(block_flag));
blank_pos.clear();
for(int i = 1; i <= 9; i ++) {
char str[15];
scanf("%s", str + 1);
for(int j = 1; j <= 9; j ++) {
mp[i][j] = str[j] - '0';
if(mp[i][j] != 0) {
set_flag(i, j, mp[i][j], 1);
}
else {
blank_pos.push_back(Pos(i, j));
}
}
}
if(dfs(blank_pos.size() - 1)) {
for(int i = 1; i <= 9; i ++) {
for(int j = 1; j <= 9; j ++) {
printf("%d", mp[i][j]);
}
printf("\n");
}
}
}
return 0;
}
题目传送:POJ - 1426 - Find The Multiple
这个题目注意到因为最多到200,打个表发现longlong可以存下答案,dfs即可
AC代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define INF 0x7fffffff
using namespace std;
int n;
bool dfs(LL ans, int ceng) {
if(ans % n == 0) {
printf("%I64d\n", ans);
return true;
}
if(ceng == 19) {
return false;
}
if(dfs(ans * 10, ceng + 1)) return true;
if(dfs(ans * 10 + 1, ceng + 1)) return true;
return false;
}
int main() {
while(scanf("%d", &n) != EOF) {
if(n == 0) break;
dfs(1LL, 1);
}
return 0;
}