2017暑假集训第一天

  今天是训练的第一天,主要复习了一下搜索的使用,包括深搜和广搜,除了复习了课件以及相关例题课件之外,完成了数道训练题目。

  总结今天的训练,认为做搜索题需要掌握其独有的方法,需要先弄清是深搜还是广搜。然后想搜什么,怎么搜,需要在哪里进行剪枝,需要在哪里进行优化。

  然后分别套用模板代码即可。

  分别是:

  BFS:

  queue<要查的对象>qq;

  while(!qq.empty()){

    下一层对象的原点=qq.front();

    判断是否到达终点:yes-结束(return);

                                    no-继续寻找。

    if(判断条件成立)qq.push(新的点);//将新得到的对象压入队列中。

   }

  在广搜中,要搜查的对象就是一开始提到的想要搜什么,怎么搜主要是指判断过程条件,达到什么条件压进队列等等。

 DFS:

  这种题型的代码类似于递归的结构:

  int search(已经搜索的次数){

    判断是否结束,yes-return

                             no-继续执行

   if(判断条件成立)//这里指找到了下一个点,search(次数+1)

   复原状态;(这里尤为重要)

  }

  这两种题在思路方面不存在很大的障碍问题,重点是读懂题意,找寻判断过程的条件,而难点就是尽可能的降低复杂度,比如今天做的一个题目:

  这个题目的主要意思就是要我们用程序玩一个数独游戏,每行每列不能重复,规定的3*3的块中也不能存在重复,这里,判断条件就是三个数组,比较好想

  但是真正的难点在于怎么减少时间的复杂度,一开始我选择在执行的过程中查找空点,再用空点进行条件判断,但这样大大拖慢了时间的复杂度,于是选择了

  换用一开始记住点的位置,对点进行查找的方法,解决了时间复杂的问题,最终处理了较难的样例。

  代码如下:

  #include<iostream>
  #include<cmath>
  #include<cstring>
  #include<algorithm>
  #include<queue>
  using namespace std;
  bool r[9][10],c[9][10],fun[10][10];
  char m[9][9];
  int total;
  struct point{
      int x;
      int y;
  };
  struct point p[100];
  void print(){
    for (int i=0;i<9;i++){
        for (int j=0;j<9;j++){
            cout<<m[i][j];
        }
        cout<<endl;
    }
 }
int judge(int xx,int yy){
    return (xx/3)*3+yy/3;
}
int  search(int n){
    int i,j,k,l;
    if (n>total)return 1;
    //cout<<total<<endl;
    for (i=1;i<=9;i++){
        //cout<<judge(p[n].x+1,p[n].y+1)<<endl;
        if (!r[p[n].x][i]&&!c[p[n].y][i]&&!fun[judge(p[n].x,p[n].y)][i]){
            m[p[n].x][p[n].y]=i+'0';
            r[p[n].x][i]=1;
            c[p[n].y][i]=1;
            fun[judge(p[n].x,p[n].y)][i]=1;
            if (search(n+1))
            return 1;
            r[p[n].x][i]=0;
            c[p[n].y][i]=0;
            fun[judge(p[n].x,p[n].y)][i]=0;
        }
    }
    return 0;
}
int main(){
    int i,j,k,l,t;
    cin>>t;
    for (k=1;k<=t;k++){
        memset (r,0,sizeof(r));
        memset (c,0,sizeof(c));
        memset (fun,0,sizeof(fun));
        for (i=0;i<9;i++){
            cin>>m[i];
        }
        for (i=0,total=0;i<9;i++){
            for (j=0;j<9;j++){
                if (m[i][j]=='0'){
                    total+=1;
                    p[total].x=i;
                    p[total].y=j;
                }
                else {
                    r[i][m[i][j]-'0']=1;
                    c[j][m[i][j]-'0']=1;
                    int kk=judge(i,j);
                    fun[kk][m[i][j]-'0']=1;
                }
            }
        }
        search(1);
        print();
    }
}

  此外还完成了4道题,其中广搜3道,深搜1道,巩固了知识点,但简单题居多,思维的发散性方面有待加强。思路有时候局限性强,导致不能想到最佳方案,便急于摸键盘,    这终究是对付水题的方案,而不是处理难题的上上策,在这方面还需加强。对于图论的相关内容出现大批遗忘,在当时就缺少训练,后来又怠于复习,更需在日后的训练中加强对这一方面的复习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值