Lights Against Dudely http://acm.hdu.edu.cn/showproblem.php?pid=4770
15个位置,所以可以暴力枚举那些放,对于放的再暴力枚举哪个转,对于转的,再枚举转哪个方向。选位置放我用了2进制枚举,选出哪个转和枚举4个方向for循环就行。可以加个小剪枝。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 const int M=256; 8 char a[M][M]; 9 struct point{ 10 int x,y; 11 friend bool operator ==(const point &a,const point &b){ 12 return a.x==b.x&&a.y==b.y; 13 } 14 }p[16]; 15 bool vis[16]; 16 int dx[]={-1,0,1,0}; 17 int dy[]={0,1,0,-1}; 18 int n,m,len,useid[16]; 19 bool isjing(const int &x,const int &y){ 20 if(x>=0&&x<n&&y>=0&&y<m&&a[x][y]=='#') return true; return false; 21 } 22 bool flag(const point &b){ 23 if(isjing(b.x,b.y)) return false; 24 for(int i=0;i<len;i++){ 25 if(b==p[i]){ 26 vis[i]=true; 27 break; 28 } 29 } 30 return true; 31 } 32 void step(point &pp,const int &dir){ 33 pp.x+=dx[dir]; 34 pp.y+=dy[dir]; 35 } 36 bool cover(const point &pp,const int &dir){ 37 if(!flag(pp)) return false; 38 point qq=pp; 39 step(qq,dir); 40 if(!flag(qq)) return false; 41 qq=pp; 42 step(qq,(dir+1)%4); 43 if(!flag(qq)) return false; 44 return true; 45 } 46 int main(){ 47 while(~scanf("%d%d",&n,&m),n|m){ 48 for(int i=0;i<n;i++){ 49 scanf("%s",a[i]); 50 } 51 len=0; 52 for(int i=0;i<n;i++){ 53 for(int j=0;j<m;j++){ 54 if(a[i][j]=='.'){ 55 p[len].x=i; 56 p[len].y=j; 57 len++; 58 } 59 } 60 } 61 int all=1<<len,ans=inf; 62 for(int i=0;i<all;i++){ 63 if(len==0) ans=0; 64 int lu=0; 65 for(int j=0;j<len;j++){ 66 if((i>>j)&1) useid[lu++]=j; 67 } 68 if(ans<=lu) continue; 69 for(int j=0;j<lu;j++){ 70 for(int dir=0;dir<4;dir++){ 71 mt(vis,0); 72 bool ok=true; 73 for(int k=0;k<lu;k++){ 74 if(k!=j){ 75 if(!cover(p[useid[k]],0)){ 76 ok=false; 77 break; 78 } 79 } 80 else{ 81 if(!cover(p[useid[k]],dir)){ 82 ok=false; 83 break; 84 } 85 } 86 } 87 if(ok){ 88 bool cc=true; 89 for(int j=0;j<len;j++){ 90 if(!vis[j]){ 91 cc=false; 92 break; 93 } 94 } 95 if(cc){ 96 ans=min(ans,lu); 97 } 98 } 99 } 100 } 101 } 102 if(ans==inf) ans=-1; 103 printf("%d ",ans); 104 } 105 return 0; 106 }
hdu 4771 http://acm.hdu.edu.cn/showproblem.php?pid=4771
bfs基础,重复状态的判断,二进制表示不同状态。题意有k个物品在图中,问最少几步全部拿到。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 using namespace std; 6 const int M=128; 7 char a[M][M]; 8 int pp[M][M]; 9 bool vis[M][M][32]; 10 int n,m,sx,sy,k; 11 struct Q{ 12 int x,y,sta,step; 13 }now,pre; 14 queue<Q> q; 15 int dx[]={0,0,1,-1}; 16 int dy[]={1,-1,0,0}; 17 int bfs(){ 18 now.x=sx; 19 now.y=sy; 20 now.sta=pp[sx][sy]; 21 now.step=0; 22 mt(vis,0); 23 vis[sx][sy][now.sta]=true; 24 while(!q.empty()) q.pop(); 25 q.push(now); 26 while(!q.empty()){ 27 pre=q.front(); 28 q.pop(); 29 if(pre.sta==(1<<k)-1) return pre.step; 30 for(int i=0;i<4;i++){ 31 int tx=pre.x+dx[i]; 32 int ty=pre.y+dy[i]; 33 if(tx>=0&&tx<n&&ty>=0&&ty<m&&a[tx][ty]!='#'&&!vis[tx][ty][pre.sta]){ 34 now.x=tx; 35 now.y=ty; 36 now.sta=pre.sta|pp[tx][ty]; 37 now.step=pre.step+1; 38 vis[tx][ty][now.sta]=true; 39 q.push(now); 40 } 41 } 42 } 43 return -1; 44 } 45 int main(){ 46 while(~scanf("%d%d",&n,&m),n|m){ 47 for(int i=0;i<n;i++){ 48 scanf("%s",a[i]); 49 for(int j=0;j<m;j++){ 50 if(a[i][j]=='@'){ 51 sx=i; 52 sy=j; 53 } 54 } 55 } 56 mt(pp,0); 57 scanf("%d",&k); 58 for(int i=0,x,y;i<k;i++){ 59 scanf("%d%d",&x,&y); 60 pp[x-1][y-1]|=(1<<i); 61 } 62 printf("%d ",bfs()); 63 } 64 return 0; 65 }
hdu 4772 Zhuge Liang's Password http://acm.hdu.edu.cn/showproblem.php?pid=4772
矩阵转4次,看哪次相等的最多。
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int M=32; 5 int a[M][M],b[M][M],c[M][M],n; 6 int solve(){ 7 for(int i=1;i<=n;i++){ 8 for(int j=1;j<=n;j++){ 9 c[n-j+1][i]=a[i][j]; 10 } 11 } 12 int res=0; 13 for(int i=1;i<=n;i++){ 14 for(int j=1;j<=n;j++){ 15 a[i][j]=c[i][j]; 16 if(a[i][j]==b[i][j]) res++; 17 } 18 } 19 return res; 20 } 21 int main(){ 22 while(~scanf("%d",&n),n){ 23 for(int i=1;i<=n;i++){ 24 for(int j=1;j<=n;j++){ 25 scanf("%d",&a[i][j]); 26 } 27 } 28 for(int i=1;i<=n;i++){ 29 for(int j=1;j<=n;j++){ 30 scanf("%d",&b[i][j]); 31 } 32 } 33 int ans=0; 34 for(int i=0;i<4;i++){ 35 ans=max(ans,solve()); 36 } 37 printf("%d ",ans); 38 } 39 return 0; 40 }
end