额,一不小心就2015年了,今天是2015年第一次刷题,就刚刚做了几道简单的dfs,因为是新年第一次刷的题嘛,所以我觉得有必要纪念下的。
代码清单:
#include<map> #include<stack> #include<cmath> #include<queue> #include<ctime> #include<cctype> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; int n; int ans; char s[5][5]; int vis[5][5]; void sign(int x,int y,int ok,int sum){ vis[x][y]=sum; for(int i=y-1;i>=0;i--){ if(s[x][i]=='X') break; if(vis[x][i]==ok) vis[x][i]=sum; } for(int i=y+1;i<n;i++){ if(s[x][i]=='X') break; if(vis[x][i]==ok) vis[x][i]=sum; } for(int i=x-1;i>=0;i--){ if(s[i][y]=='X') break; if(vis[i][y]==ok) vis[i][y]=sum; } for(int i=x+1;i<n;i++){ if(s[i][y]=='X') break; if(vis[i][y]==ok) vis[i][y]=sum; } } void dfs(int x,int sum){ if(x==n){ if(sum>ans) ans=sum; return ; } for(int i=0;i<n;i++){ if(s[x][i]!='X'&&vis[x][i]==0){ sign(x,i,0,sum+1); dfs(x,sum+1); sign(x,i,sum+1,0); continue; } } dfs(x+1,sum); } int main(){ while(scanf("%d",&n)!=EOF&&n){ memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++) scanf("%s",s[i]); ans=-1; dfs(0,0); printf("%d\n",ans); }return 0; }
题意:给定一些木条,问你能否把他们拼成一个正方形。
分析:加了一点点减枝,就是当前形成的木条长度小于木棍总和的1/4时,直接往后找,而不是又从0开始找。
代码清单:
#include<map> #include<stack> #include<cmath> #include<queue> #include<ctime> #include<cctype> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; int T; int n,sum; int a[25]; int vis[25]; bool ok; void dfs(int sun,int tot,int pos){ if(tot==4){ ok=true; return ; } if(ok) return ; for(int i=pos;i<n;i++){ if(!vis[i]){ if(sun+a[i]==sum){ vis[i]=1; dfs(0,tot+1,0); if(ok) return ; vis[i]=0; } else if(sun+a[i]<sum){ vis[i]=1; dfs(sun+a[i],tot,i+1); if(ok) return ; vis[i]=0; } } } } int main(){ scanf("%d",&T); while(T--){ sum=0; scanf("%d",&n); memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++){ scanf("%d",&a[i]); sum+=a[i]; } if(n<4 || sum%4) printf("no\n"); else{ sum/=4; ok=false; dfs(0,0,0); if(ok) printf("yes\n"); else printf("no\n"); } }return 0; }
题意:额,是中文题,就不说题意咯。
分析:直接根据题意去搜,记得转弯次数小于2就可以了。我把turn初始化成-1的原因是因为往外面踏出的第一步是不算转弯的,所以看代码里计算一下的话第一次踏出去turn就会变成0。
代码清单:
#include<map> #include<stack> #include<cmath> #include<queue> #include<ctime> #include<cctype> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; bool ok; int n,m,p; int rx,ry,x2,y2; int num[1005][1005]; int vis[1005][1005]; int xy[4][2]={{0,-1},{-1,0},{0,1},{1,0}}; bool judge(int x,int y){ if(x>=0&&x<n&&y>=0&&y<m&&num[x][y]==0) return true; return false; } void dfs(int x,int y,int turn,int dir){ if(x==x2&&y==y2){ ok=true; return ; } for(int i=0;i<4;i++){ int xx=x+xy[i][0]; int yy=y+xy[i][1]; if(judge(xx,yy)&&!vis[xx][yy]){ if(dir!=i&&turn+1<=2){ vis[xx][yy]=1; dfs(xx,yy,turn+1,i); if(ok) return ; vis[xx][yy]=0; } else if(dir==i){ vis[xx][yy]=1; dfs(xx,yy,turn,i); if(ok) return ; vis[xx][yy]=0; } } } } int main(){ while(scanf("%d%d",&n,&m)!=EOF&&n&&m){ for(int i=0;i<n;i++) for(int j=0;j<m;j++) scanf("%d",&num[i][j]); scanf("%d",&p); while(p--){ scanf("%d%d%d%d",&rx,&ry,&x2,&y2); rx--;ry--;x2--;y2--; if(num[rx][ry]!=num[x2][y2]) printf("NO\n"); else if(num[rx][ry]==0 || num[x2][y2]==0) printf("NO\n"); else{ ok=false; int ret=num[x2][y2]; num[x2][y2]=0; memset(vis,0,sizeof(vis)); dfs(rx,ry,-1,-1); if(ok) printf("YES\n"); else printf("NO\n"); num[x2][y2]=ret; } } }return 0; }