HDU_1045 Fire Net
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1045
题意:
4 .X.. .... XX.. ....
给你n*n的图,‘X‘表示墙,在图中填黑点,一行(或一列)中不能有两可以直达的点(即:一行(列)中任意两点有墙相隔。
思路:由于n<=4,所以直接二进制枚举了。然后用check(int cur)函数判断是否可行。
//据说这题是贪心。。。。
代码:
/************************************************ * Author: Ac_sorry * File: * Create Date: * Motto: One heart One life * CSDN: http://blog.csdn.net/code_or_code *************************************************/ #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<cstdlib> #include<vector> #include<string> #include<utility> #include<map> #include<set> #include<queue> #include<stack> #define INF 0x3f3f3f3f #define MOD 1000000007 #define seed_ 131 #define eps 1e-8 #define mem(a,b) memset(a,b,sizeof a) #define w(i) tree[i].w #define ls(i) tree[i].ls #define rs(i) tree[i].rs using namespace std; typedef long long LL; const int N=100010; char gra[10][10]; int vis[10][10]; int n; int check(int cur) { int cnt=0; mem(vis,0); for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if(gra[i][j]=='X') vis[i][j]=2; } } for(int i=0;i<n*n;i++) { if(cur&(1<<i)) { if(vis[i/n][i%n]) return -1; //cout<<i<<"-"<<endl; vis[i/n][i%n]=1; cnt++; } } int flag; for(int i=0;i<n;i++) { flag=0; for(int j=0;j<n;j++) { if(vis[i][j]==1) { if(flag) return -1; flag=1; } else if(vis[i][j]==2) flag=0; } } for(int j=0;j<n;j++) { flag=0; for(int i=0;i<n;i++) { if(vis[i][j]==1) { if(flag) return -1; flag=1; } else if(vis[i][j]==2) flag=0; } } return cnt; } int main() { while(scanf("%d",&n)==1) { if(n==0) break; for(int i=0;i<n;i++) scanf("%s",gra[i]); int ans=0; for(int i=0;i<(1<<(n*n));i++) { ans=max(ans,check(i)); //cout<<i<<"--\n"; } printf("%d\n",ans); } return 0; }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。