搜索练习 (主要练剪枝23333)
Posted 一入OI深似海
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搜索练习 (主要练剪枝23333)相关的知识,希望对你有一定的参考价值。
/* hdu 1010 Tempter of the Bone 尼玛博客里的题目描述不对...加个奇偶剪枝 可以证明 两个点之间任意距离与欧几里得距离同奇偶 奇偶剪枝 可行性剪枝 特判剪枝... */ #include<iostream> #include<cstdio> using namespace std; int n,m,T,sx,sy,ex,ey; bool falg; char s[10][10]; int xx[4]={0,0,1,-1}; int yy[4]={1,-1,0,0}; int Abs(int x){ return x>0?x:-x; } void Dfs(int x,int y,int t){ int S=Abs(ex-x)+Abs(ey-y); if((S%2&&t%2==0)||(S%2==0&&t%2))return; if(t<0||S>t)return; if(t==0&&x==ex&&y==ey){ falg=1;return; } for(int i=0;i<4;i++){ int nx=x+xx[i]; int ny=y+yy[i]; if(nx>0&&nx<=n&&ny>0&&ny<=m&&s[nx][ny]==‘.‘){ s[nx][ny]=‘X‘; Dfs(nx,ny,t-1);if(falg)return; s[nx][ny]=‘.‘; } } } int main() { while(1){ scanf("%d%d%d",&n,&m,&T); if(n==0&&m==0&&T==0)break; falg=0;int cnt=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ cin>>s[i][j]; if(s[i][j]==‘S‘)sx=i,sy=j,s[i][j]=‘X‘; if(s[i][j]==‘D‘)ex=i,ey=j,s[i][j]=‘.‘; if(s[i][j]==‘.‘)cnt++; } if(cnt+1<T){ printf("NO\n");continue; } Dfs(sx,sy,T); if(falg)printf("YES\n"); else printf("NO\n"); } return 0; }
/* codevs 1288 埃及分数 迭代+剪枝*/ #include<iostream> #include<cstdio> #define ll long long #define C 0.0000001 #define mem(a,b) for(int i=0;i<now;i++)a[i]=c[i]; using namespace std; ll a,b,falg,sum,ans[110],c[110]; ll Gcd(ll x,ll y){ return y?Gcd(y,x%y):x; } ll Ceil(double x){ return int(x+0.99999999); } ll max(ll x,ll y){ return x>y?x:y; } void Dfs(ll x,ll y,ll now){ ll gcd=Gcd(x,y); x/=gcd;y/=gcd; if(now==sum){ if(x==0){ if(falg){ if(c[now-1]<ans[now-1])mem(ans,c); } else mem(ans,c); falg=1; } return; } ll l=Ceil(double(y)/double(x));// 计算左边界 ll r=Ceil((double(sum)-double(now))/(double(x)/double(y)));//计算右边界 for(int i=max(l,c[now-1]+1);i<=r;i++){ if(falg&&i>ans[sum-1])return; //这个一开写的是再选最后一位的时候才剪 其实只有存过答案了 不管哪一位都能剪 因为后面的一定比这个大 c[now]=i;Dfs(x*i-y,y*i,now+1);c[now]=0; } } int main() { cin>>a>>b; for(sum=1;sum<=20;sum++){ Dfs(a,b,0); if(falg)break; } for(int i=0;i<sum;i++) cout<<ans[i]<<" "; return 0; }
/* poj 1416 Shredding Company 简单搜索*/ #include<cstdio> #include<cstring> #define mem(a,b) for(int i=1;i<=8;i++)a[i]=b[i]; #define mes(a) for(int i=1;i<=8;i++)a[i]=0; using namespace std; int len,target,a[10],c[10],mxx,sum,ans[10]; char s[10]; void Dfs(int now){ if(now==len){ int mx=0,p=1; while(p<=len){ int x=a[p]; while(c[p]==0&&p<len){ p++;x=x*10+a[p]; } mx+=x;p++; } if(mx<=target&&mx>mxx){ mxx=mx;sum=1;mem(ans,c); } else if(mx<=target&&mx==mxx)sum++; return; } c[now]=1;Dfs(now+1); c[now]=0;Dfs(now+1); } int main() { for(;;){ scanf("%d%s",&target,s); mxx=sum=0;mes(c); if(target==0&&s[0]==‘0‘)break; len=strlen(s); for(int i=1;i<=len;i++) a[i]=s[i-1]-‘0‘; Dfs(1); if(sum==0)printf("error\n"); else if(sum>1)printf("rejected\n"); else { printf("%d ",mxx); for(int i=1;i<=len;i++){ printf("%d",a[i]); if(ans[i])printf(" "); } printf("\n"); } } return 0; }
以上是关于搜索练习 (主要练剪枝23333)的主要内容,如果未能解决你的问题,请参考以下文章