DFS的基础训练清单

HDU 1010  (AC)

HDU 1015    (AC)

HDU 1016     (AC)

HDU 1172   (AC)

HDU 1312   (AC)

POJ 2362  (AC,1011的弱化版,建议先做这题)

POJ  1011  (AC,强烈推荐)

POJ  3620  

HDU 1010代码

/*******************************************************************************/
/* OS           : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
 * Compiler     : g++ (GCC)  4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
 * Encoding     : UTF8
 * Date         : 2014-03-24
 * All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

char a[10][10];
int x_d[]={1,-1,0,0};
int y_d[]={0,0,-1,1};

int mabs(int i){return i>0?i:-i;}
int m,n,dr_i,dr_j;
int dfs(int x,int y,int t){
    if(mabs(dr_i-x)+mabs(dr_j-y)>t){
             return 0;
    }
    //奇偶剪枝
    if(((mabs(x-dr_i)+mabs(y-dr_j))&1)==0&&(t&1)) return 0;
    if(((mabs(x-dr_i)+mabs(y-dr_j))&1)&&(t&1)==0) return 0;
    int i,j,k;
    for(k=0;k<4;k++){
        i=x+x_d[k];
        j=y+y_d[k];   //四个方向
        if(i<0||i>=n||j<0||j>=m) continue ;//保证不越界
        if(t==1){
           if(i==dr_i&&j==dr_j) return 1; //到了
           continue;
        }
        if(a[i][j]!='.') continue;
        a[i][j]='X';
        if(dfs(i,j,t-1)) return 1;
         a[i][j]='.';

    }
    return 0;

}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    int t;
    int i,j;
    int st_i,st_j;
    while(cin>>n>>m>>t&&(n||m||t)){
        for(i=0;i<n;i++)
            for(j=0;j<m;j++){
              cin>>a[i][j];
              if(a[i][j]=='S'){
                  st_i=i;
                  st_j=j;

              }else if(a[i][j]=='D'){
                  dr_i=i;
                  dr_j=j;

              }
            }
        if(mabs(dr_i-st_i)+mabs(dr_j-dr_j)>t){
             cout<<"NO
";
             continue;
        }

        if(dfs(st_i,st_j,t)) cout<<"YES
";
        else cout<<"NO
";





    }

    #ifndef  ONLINE_JUDGE
    fclose(stdin);
    #endif

    return 0;

}




1016这题目,我觉得我的做法还是很暴力的,有了1010的基础……没参考任何人,写出来的。没有怎么优化。800MS……的确慢。。不过理解还是很容易的。。n

PE了一次,因为我没看到是每组都输出空行……最后一组测试输出空行就通过了。

/*******************************************************************************/
/* OS           : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
 * Compiler     : g++ (GCC)  4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
 * Encoding     : UTF8
 * Date         : 2014-03-27
 * All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[][10]={{0},{2,4,6,10,12,16,18},
{1,3,5,9,11,15,17},
{2,4,8,10,14,16},
{1,3,7,9,13,15,19},
{2,6,8,12,14,18},
{1,5,7,11,13,17},
{4,6,10,12,16},
{3,5,9,11,15},
{2,4,8,10,14},
{1,3,7,9,13,19},
{2,6,8,12,18},
{1,5,7,11,17,19},
{4,6,10,16,18},
{3,5,9,15,17},
{2,4,8,14,16},
{1,3,7,13,15},
{2,6,12,14},
{1,5,11,13,19},
{4,10,12,18},
{3,9,11,17}};
int n;
int vist[22],nxt[22];
bool isprime(int k){
   int t=2;
   for(;t*t<=k;t++)
     if(k%t==0) return 0;

     return 1;


}
void dfs(int cur,int nt){

   int i=0;
   while(a[cur][i]!=0&&a[cur][i]<=n){

      if(vist[a[cur][i]]==0){
         vist[a[cur][i]]=1;
         nxt[cur]=a[cur][i];

         if(nt==2&&isprime(a[cur][i]+1)){
            int p=1;
            cout<<1;
             while(nxt[p]!=a[cur][i]){
               cout<<" "<<nxt[p];
               p=nxt[p];

             }
             cout<<" "<<a[cur][i]<<endl;
              vist[a[cur][i]]=0;
             return ;

         }
         dfs(a[cur][i],nt-1);
          vist[a[cur][i]]=0;


      }


      i++;
   }




}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    int cs=0;
    while(cin>>n){

      cs++;

      memset(vist,0,sizeof(vist));
       vist[1]=1;
      cout<<"Case "<<cs<<":
";
      if(n==1) cout<<1<<endl;
      else dfs(1,n);
      cout<<endl;


    }


    #ifndef  ONLINE_JUDGE
    fclose(stdin);
    #endif

    return 0;

}


其实我也不知道1015叫做暴力呢,还是深搜,还是深搜暴力呢。。。

0ms通过,出乎我意料。。。我以为数据会很多。。。

从高位开始枚举,第一个结果输出即可。我用bitmap排了一下序。这么小的数据,用bitmap最合适不过了。。。so easy.1A

/*******************************************************************************/
/* OS           : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
 * Compiler     : g++ (GCC)  4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
 * Encoding     : UTF8
 * Date         : 2014-03-27
 * All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
int target;
string psw;
int vist[30];
vector<int> v;
bool isF(int a,int b,int c,int d,int e)
{
    int dd=d*d;
    int ee=e*e;
    //v - w^2 + x^3 - y^4 + z^5 = target
    if(a-b*b+c*c*c-dd*dd+ee*ee*e==target)
    {
        return 1;
    }
    return 0;


}
void dfs()
{
    //a - b^2 + c^3 - d^4 + e^5 = target

    int a,b,c,d,e;


    int siz=v.size();
    int i,j,k,l,m;
    for(i=0; i<siz; i++)
    {
        if(vist[i]==-1) continue;
        a=v[i];
        vist[i]=-1;
        for(j=0; j<siz; j++)
        {
            if(vist[j]==-1) continue;
            b=v[j];
            vist[j]=-1;
            for(k=0; k<siz; k++)
            {
                if(vist[k]==-1) continue;
                vist[k]=-1;
                c=v[k];
                for(l=0; l<siz; l++)
                {
                    if(vist[l]==-1 ) continue;
                    vist[l]=-1;
                    d=v[l];
                    for(m=0; m<siz; m++)
                    {
                        if(vist[m]==-1) continue;
                        vist[m]=-1;
                        e=v[m];

                        if(isF(a,b,c,d,e))
                        {
                            cout<<(char)('A'-1+a)<<(char)('A'-1+b)<<(char)('A'-1+c)<<(char)('A'-1+d)<<(char)('A'-1+e)<<endl;
                            return;
                        }
                        vist[m]=0;  //恢复


                    }
                    vist[l]=0;  //恢复

                }
                vist[k]=0;  //恢复
            }
            vist[j]=0;  //恢复
        }
        vist[i]=0;  //恢复

    }


    cout<<"no solution
";



}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    while(cin>>target>>psw)
    {
         memset(vist,0,sizeof(vist));
        if(target==0&&psw=="END") break;
        int len=psw.length();
        for(int i=0; i<len; i++)
            vist[psw[i]-'A']=1;
        v.clear();
        for(int i=25; i>=0; i--)
            if(vist[i]==1) v.push_back(i+1);
        dfs();



    }



#ifndef  ONLINE_JUDGE
    fclose(stdin);
#endif

    return 0;

}



HDU1172

/*******************************************************************************/
/* OS           : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
 * Compiler     : g++ (GCC)  4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
 * Encoding     : UTF8
 * Date         : 2014-04-01
 * All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
class Num{
 public:
    Num(){}
    int nb,n,k;

};
int a[4];
int b[4];
int mp1[10];
int mp2[10];

bool isLegal(int i,Num N){

   int j=N.nb,k,cnt=0;
   for(k=0;k<4;k++){
      a[k]=i%10;
      i/=10;
      b[k]=j%10;
      j/=10;
      if(a[k]==b[k]) cnt++;

   }

   if(cnt!=N.k){ return 0;}
   //满足相同的数后
   memset(mp1,0,sizeof(mp1));
   memset(mp2,0,sizeof(mp2));
   cnt=0;
   for(k=0;k<4;k++){
      mp1[a[k]]++;
      mp2[b[k]]++;
    }
   for(k=0;k<10;k++){
      cnt+=min(mp1[k],mp2[k]);
   }
   if(cnt!=N.n) return 0;
   return 1;



}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    int N,i,j;
    vector<Num> v;
    int res;
    while(cin>>N&&N){
      res=0;
      v.clear();
      v.resize(N);
      for(i=0;i<N;i++){
         cin>>v[i].nb>>v[i].n>>v[i].k;
       }
      for(i=1000;i<10000;i++){
          for(j=0;j<N;j++){
             if(!isLegal(i,v[j])){   //满足与否
                break;
              }
          }
          if(j==N){
             if(res==0){
              res=i;

             }else{

                res=0;  //第二次赋值,直接break.同时列入not sure状态,我没有用特殊的flag来区分,没必要~
                break;
             }
          }

      }
      if(res) cout<<res<<endl;
      else cout<<"Not sure"<<endl;




    }


    #ifndef  ONLINE_JUDGE
    fclose(stdin);
    #endif

    return 0;

}



这题太暴力了~15MS 水过。。


hdu1312还是水题!

/*******************************************************************************/
/* OS           : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
 * Compiler     : g++ (GCC)  4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
 * Encoding     : UTF8
 * Date         : 2014-04-13
 * All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char mp[30][30];
bool visit[30][30];
int dfs(int i,int j){

   int cnt=0;
   if(mp[i][j]=='.'&&visit[i][j]==0){
       cnt++;
       visit[i][j]=1;
       cnt+=dfs(i+1,j);
       cnt+=dfs(i,j-1);
       cnt+=dfs(i-1,j);
       cnt+=dfs(i,j+1);
       return cnt;

   }
   return cnt;



}
int main(){
    #ifndef ONLINE_JUDGE
   freopen("input.txt","r",stdin);
    #endif
    int n,m;
    char c;
    int st_i,st_j;
    while(cin>>n>>m&&(n||m)){
       memset(visit,0,sizeof(visit));
       memset(mp,'#',sizeof(mp));
      for(int i=1;i<=m;i++)
       for(int j=1;j<=n;j++){
          cin>>c;
          if(c=='@'){
            st_i=i;
            st_j=j;
          }
          mp[i][j]=c;
       }
     //  cout<<st_i<<" "<<st_j<<endl;
      int cnt=1;
      cnt+=dfs(st_i+1,st_j);
     // cout<<cnt<<"s1"<<endl;
      cnt+=dfs(st_i,st_j-1);
    //  cout<<cnt<<"s2"<<endl;
      cnt+=dfs(st_i-1,st_j);
    //  cout<<cnt<<"s3"<<endl;
      cnt+=dfs(st_i,st_j+1);
      cout<<cnt<<endl;




    }


    #ifndef  ONLINE_JUDGE
   fclose(stdin);
    #endif

    return 0;

}


poj 2362

很好的搜索剪枝!!!

/*******************************************************************************/
/* OS           : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
 * Compiler     : g++ (GCC)  4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
 * Encoding     : UTF8
 * Date         : 2014-04-13
 * All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int M[25];
bool visit[25];
int edge,n;
bool dfs(int num,int len,int beg){
  if(num==3){
     return true;
  }
  for(int i=beg;i<=n;i++){
     if(!visit[i]){
        visit[i]=1;

        if(len+M[i]==edge&&dfs(num+1,0,0)){
           return true; ;
        }
        if(len+M[i]<edge&&dfs(num,len+M[i],i+1)){
          return true;

        }


        visit[i]=0;

     }



  }


  return false;

}

int main(){
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    #endif
    int T;
    while(cin>>T){
       while(T--){
           cin>>n;
           edge=0;
          for(int i=1;i<=n;i++){
             cin>>M[i];
             edge+=M[i];

          }
          if(edge%4!=0){
             cout<<"no
";
          }else{
             edge>>=2;
             sort(M+1,M+n+1);
             if(M[1]==M[n]){

               if(n%4==0){
                cout<<"yes
";
               }else{
                 cout<<"no
";
               }

             }else{
                memset(visit,0,sizeof(visit));
                if(M[n]>edge) cout<<"no
";
                else if(dfs(0,0,0)) cout<<"yes
";
                else cout<<"no
";


             }


          }
          /*
          for(int i=1;i<=n;i++)
            cout<<M[i]<<endl;
          */

       }



    }


    #ifndef  ONLINE_JUDGE
    fclose(stdin);
    #endif

    return 0;

}




poj 1011

大开眼界的剪枝。

/*******************************************************************************/
/* OS           : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
 * Compiler     : g++ (GCC)  4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
 * Encoding     : UTF8
 * Date         : 2014-04-13
 * All Rights Reserved by yaolong.
*****************************************************************************/
/* Description: ***************************************************************
*****************************************************************************/
/* Analysis: ******************************************************************
*****************************************************************************/
/*****************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int M[80];
bool visit[80];
int edge,n,p,sum;
bool cmp(int a,int b){
  return a>b;
}
bool dfs(int num,int len,int beg){
  if(num==p){
     return true;
  }
  int sample=-1;
  for(int i=beg;i<=n;i++){
     if(!visit[i]&&M[i]!=sample){
        visit[i]=1;


        if(len+M[i]==edge){
          if(dfs(num+1,0,0))
           return true; ;
           sample=M[i];
        }
        else if(len+M[i]<edge){
          if(dfs(num,len+M[i],i+1))
          return true;
          sample=M[i];
        }


        visit[i]=0;
       if(len==0) break;

     }



  }


  return false;

}
int solve(){

 for(int len=M[1];len<=sum-len;len++){
              if(sum%len==0){

                memset(visit,0,sizeof(visit));
                p=sum/len;
                edge=len;
                // cout<<p<<endl;;
                if(dfs(0,0,0)){
                  return len;
                };

              }

}
return sum;


}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
    #endif


       while(cin>>n&&n){

          sum=0;
          for(int i=1;i<=n;i++){
             cin>>M[i];
             sum+=M[i];

          }


           sort(M+1,M+n+1,cmp);
          // cout<<M[1]<<endl;
          int ans=solve();
           cout<<ans<<endl;

          }
          /*
          for(int i=1;i<=n;i++)
            cout<<M[i]<<endl;
          */








    #ifndef  ONLINE_JUDGE
    fclose(stdin);
    #endif

    return 0;

}




原文地址:https://www.cnblogs.com/dengyaolong/p/3697211.html