zoukankan      html  css  js  c++  java
  • 搜索练习 (主要练剪枝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
    ");continue;
            }
            Dfs(sx,sy,T);
            if(falg)printf("YES
    ");
            else printf("NO
    ");
        }
        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
    ");
            else if(sum>1)printf("rejected
    ");
            else {
                printf("%d ",mxx);
                for(int i=1;i<=len;i++){
                    printf("%d",a[i]);
                    if(ans[i])printf(" ");
                }
                printf("
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    后缀数组 (Suffix Array) 学习笔记
    Miller-Rabin 素性测试 与 Pollard Rho 大整数分解
    [ USACO 2013 OPEN ] Photo
    清华集训2016做题记录
    「UNR#2」黎明前的巧克力
    「UNR#1」奇怪的线段树
    Atcoder Grand Contest 018 E
    「NOI2015」小园丁与老司机
    「集训队作业2018」三角形
    Codeforces 878 E. Numbers on the blackboard
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5977671.html
Copyright © 2011-2022 走看看