历届试题 剪格子 IDA*

来源:互联网 发布:淘宝网刷单平台 编辑:程序博客网 时间:2024/04/29 02:47

         思路:限制当前能剪下的最大格子数,保证能得到最少数目。IDA*的典型运用。

AC代码

#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <utility>#include <string>#include <iostream>#include <map>#include <set>#include <vector>#include <queue>#include <stack>using namespace std;#pragma comment(linker, "/STACK:1024000000,1024000000") #define eps 1e-10#define inf 0x3f3f3f3f#define PI pair<int, int> typedef long long LL;const int maxn = 10 + 5;int vis[maxn][maxn], a[maxn][maxn];int n, m, maxd, goal;const int dx[] = {0,0,-1,1};const int dy[] = {1,-1,0,0};// IDA*int w;int dfs(int x, int y, int sum, int cnt) {if(sum == goal) return 1;if(cnt >= maxd) {w = min(w, sum);return 0;}vis[x][y] = 1;for(int i = 0; i < 4; ++i) {int px = x + dx[i], py = y + dy[i];if(px < 0 || py < 0 || px >= n || py >= m || vis[px][py]) continue;if(sum + a[px][py] > goal) continue;if(dfs(px, py, sum + a[px][py], cnt + 1)) return 1;}vis[x][y] = 0;return 0;}int main() {while(scanf("%d%d", &m, &n) == 2) {int sum = 0;for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) {scanf("%d", &a[i][j]);sum += a[i][j];}if(sum & 1) {printf("0\n");continue;}memset(vis, 0, sizeof(vis));goal = sum / 2;int flag = 0;for(maxd = 1; maxd < n*m; ++maxd) {w = inf;if(dfs(0, 0, a[0][0], 1)) {flag = 1;printf("%d\n", maxd);break;}if(w > goal) break;}if(!flag) printf("0\n");}return 0;}

如有不当之处欢迎指出!

0 0