zoukankan      html  css  js  c++  java
  • 【蓝桥杯2016_C++】t3:方格填数

    如下的10个格子

    填入0~9的数字。要求:连续的两个数字不能相邻。
    (左右、上下、对角都算相邻)

    一共有多少种可能的填数方案?

    请填写表示方案数目的整数。

    法一

    全排列+check,可以把这个格子当成一个存放0~9的一维数组再进行全排列,把每种不符合要求的条件都列出来check一下:

     1 #include <iostream>
     2 #include <algorithm>
     3 using namespace std;
     4 int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
     5 int ans = 0;
     6 bool check(){
     7     if(abs(a[0]-a[1])==1 || abs(a[0]-a[3])==1 || abs(a[0]-a[4])==1 || abs(a[0]-a[5])==1
     8     || abs(a[1]-a[2])==1 || abs(a[1]-a[4])==1 || abs(a[1]-a[5])==1 || abs(a[1]-a[6])==1
     9     || abs(a[2]-a[5])==1 || abs(a[2]-a[6])==1
    10     || abs(a[3]-a[4])==1 || abs(a[3]-a[7])==1 || abs(a[3]-a[8])==1
    11     || abs(a[4]-a[5])==1 || abs(a[4]-a[7])==1 || abs(a[4]-a[8])==1 || abs(a[4]-a[9])==1
    12     || abs(a[5]-a[6])==1 || abs(a[5]-a[8])==1 || abs(a[5]-a[9])==1
    13     || abs(a[6]-a[9])==1
    14     || abs(a[7]-a[8])==1
    15     || abs(a[8]-a[9])==1
    16     ) return false;
    17     else{
    18         ans++;
    19         return true;    
    20     }
    21 }
    22 int main()
    23 {
    24     do{
    25         check();
    26     }while(next_permutation(a,a+10));    
    27     cout<<ans;
    28     return 0;
    29 }

    有一个手动实现全排列的模板:

     1 /*考虑第k个位置,一般从0开始*/
     2 void f(int k) {
     3 //出口
     4     if (k == 10) {
     5         bool b = check();
     6         if(b)
     7             ans++;
     8         return;
     9     }
    10 
    11 
    12     for (int i = k; i < 10; ++i) {
    13         //尝试将位置i与位置k交换,以此确定k位的值
    14         {
    15             int t = a[i];
    16             a[i] = a[k];
    17             a[k] = t;
    18         }
    19         f(k + 1);
    20 //        回溯
    21         {
    22             int t = a[i];
    23             a[i] = a[k];
    24             a[k] = t;
    25         }
    26 
    27     }
    28 }

    法二

    check列出来可能很乱,还有一种方法,就是把方格扩展成5*6的二维数组,先把所有格子都初始化为-10(除了-1,其他负数比如-5、-7都可):

    check改为把每个元素和它周围一圈的元素做差取绝对值判断,写起来就简洁很多。扩展方格是为了防止check时下标越界。

    从第一个格子(1,2)开始,从0~9中选一个没有被标记过的填进去,然后把填进去的数标记成已访问;然后check提前剪枝,满足条件就下一层递归,否则格子恢复-10的值并continue。最后还要回溯,标记清零。

    这种方法每填一个格子就会提前check剪枝,不像法一,全部排列完才进行判断,提高了效率。

     1 #include <iostream>
     2 #include <algorithm>
     3 using namespace std;
     4 int a[5][6];
     5 int vis[10];
     6 int ans = 0;
     7 void init(){
     8     for(int i=0;i<5;i++)
     9         for(int j=0;j<6;j++)
    10             a[i][j] = -10;
    11 }
    12 bool check(int x,int y){
    13     for(int i = x-1;i<=x+1;i++)
    14         for(int j = y-1;j<=y+1;j++)
    15             if(abs(a[x][y]-a[i][j])==1) return false;
    16     return true;
    17 }
    18 void f(int x,int y){
    19     if(x==3 && y==4){  //如果已经填完了最后一个格子 
    20         ans++;
    21         return;
    22     }
    23     for(int i = 0;i<10;i++){
    24         if(vis[i]==0){  //从0~9选一个没有填过的数字 
    25             a[x][y] = i;
    26             if(!check(x,y)){ //如果不满足check条件 
    27                 a[x][y] = -10;  //恢复并continue 
    28                 continue;
    29             }
    30             vis[i] = 1; //满足条件,标记并继续填下一个格子 
    31             if(y==4) f(x+1,1);  //换行 
    32             else f(x,y+1); //继续填右侧格子 
    33             //回溯
    34             vis[i] = 0;
    35             a[x][y] = -10; 
    36         }
    37     }
    38 }
    39 int main()
    40 {
    41     init();
    42     f(1,2);
    43     cout<<ans<<endl;     
    44     return 0;
    45 }
  • 相关阅读:
    JavaScript构造函数学习笔记
    JavaScript面向对象编程学习笔记
    Maven学习--Maven项目目录、Maven坐标
    Maven学习--安装说明
    Watir问题---gem install watir-classic报错: ERROR: Error installing watir-classic: ERROR: Failed to build gem native extension.
    TestLink问题 —图表中文乱码
    TeskLink—增加一种需求类型(业务流程)(version1.9.8)
    Watir问题--LoadError: cannot load such file -- watir-classic
    Watir--Ruby + Watir环境安装
    Watir问题--Selenium::WebDriver::Error::WebDriverError: unexpected response, code=502, content-type="text/html"
  • 原文地址:https://www.cnblogs.com/Aikoin/p/10584673.html
Copyright © 2011-2022 走看看