标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1045
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8185 Accepted Submission(s): 4691
/* 本题思路: 暴力DFS, 每个点都先假设放上子弹, 然后判断是否成立再DFS。不过在分别判断行和列是否合法 时, 是从小到大DFS的, 所以只判断前面的即可! */ #include<cstdio> #include<cstring> #include<algorithm> using namespace std; char pic[10][10]; int ans, n; int Judge(int row, int col) { for(int i=col-1; i>=0; i--)//判断所在列 { if(pic[row][i]==‘a‘) return false; if(pic[row][i]==‘X‘) break; } for(int i=row-1; i>=0; i--)//判断所在行 { if(pic[i][col]==‘a‘) return false; if(pic[i][col]==‘X‘) break; } return true; } void dfs(int cur, int tot) { if(cur==n*n) { ans = max(ans, tot); return; } else { int row = cur/n;//这里是一个很有意思的小技巧 int col = cur%n; if(pic[row][col]==‘.‘&&Judge(row, col)) { pic[row][col]=‘a‘; dfs(cur+1, tot+1); pic[row][col] = ‘.‘; } dfs(cur+1, tot); } } int main() { while(scanf("%d", &n), n) { memset(pic, 0, sizeof(pic)); for(int i=0; i<n; i++) scanf("%s", pic[i]); ans = 0; dfs(0, 0); printf("%d\n", ans); } return 0; }
然而上述代码有一个缺陷,前面的行和列坑能合理。但是可能放置子弹后(后面也有子弹且无墙),导致不合理。 然而这道题的数据奇弱,因此能过。
下述代码虽然比上面的跑的稍慢,但仍是0ms飘过。(这道题的数据规模真是亲民)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; char pic[10][10]; int ans, n; int Judge(int row, int col) { for(int i=n-1; i>=0; i--)//判断所在列 { if(pic[row][i]==‘a‘) return false; if(pic[row][i]==‘X‘) break; } for(int i=n-1; i>=0; i--)//判断所在行 { if(pic[i][col]==‘a‘) return false; if(pic[i][col]==‘X‘) break; } return true; } void dfs(int cur, int tot) { if(cur==n*n) { ans = max(ans, tot); return; } else { int row = cur/n;//这里是一个很有意思的小技巧 int col = cur%n; if(pic[row][col]==‘.‘&&Judge(row, col)) { pic[row][col]=‘a‘; dfs(cur+1, tot+1); pic[row][col] = ‘.‘; } dfs(cur+1, tot); } } int main() { while(scanf("%d", &n), n) { memset(pic, 0, sizeof(pic)); for(int i=0; i<n; i++) scanf("%s", pic[i]); ans = 0; dfs(0, 0); printf("%d\n", ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/acm1314/p/4774436.html