宝石排列问题

宝石排列问题西安交大软件 53 nbsp 蔡少斐题号 5 10 题目叙述 现有 n 种不同形状的宝石 每种 n 颗 共 n n 颗 同一形状的 n 颗宝石分别具有 n 种不同的颜色 c1 c2 cn 中的一种颜色 欲将这 n n 颗宝石排列成 n 行 n 列的一个方阵 使方阵中每一行和每一列的宝石都有 n 种不同的形状和 n 种不同颜色 是设计一个算法 计算出对于给定的 n 有多少种不同的宝石排列方案 输入数据 只有一个整数 n 输出数据

西安交大 软件53  蔡少斐

题号:5_10

题目叙述:

现有n种不同形状的宝石,每种n颗,共n*n颗。同一形状的n颗宝石分别具有n种不同的颜色c1,c2,…,cn中的一种颜色。欲将这n*n颗宝石排列成n行n列的一个方阵,使方阵中每一行和每一列的宝石都有n种不同的形状和n种不同颜色。是设计一个算法,计算出对于给定的n,有多少种不同的宝石排列方案。

输入数据:

只有一个整数n

输出数据:

一个整数,代表不同的宝石排列方案。

题目解答:

       问题将采用回溯法解决,首先搜索其所有的解空间,并生成解空间树,将满足条件的情况记录下来。

       由于要求每一行宝石的形状和颜色均不相同,因此我们可以从行开始,生成行的有效全排列,然后对刚生的位置进行列有效判定,如果成功则继续向下搜索,不成功则重新生成排列,继续判定。

       实现细节:在行进行生成2个排列的时候,先生成形状的排列,然后对形状进行列有效判定,若成功则进一步生成行颜色排列,并对颜色进行列有效判定。若都成功,那么这一颗石子也就确定了,则检验该石子是否在以前出现过,若出现过则放置失败,继续进行同级搜索,否则的话,我们就该考虑向下一个位置的搜索了。

       下一个位置的确定有3种情况,第一种是如果当前位置为(n,n)那么不继续进行搜索,而是Ans++。第二种情况是如果当前位置为(x,n)那么下一个搜索的位置就是(x+1,1)。

另外,在进行列有效判定时,采用了std::set数据结构进行辅助设计,可以加速判定。

代码实现:

#include 
  
    #include 
   
     #include 
    
      #include 
     
       usingnamespace std; int used[10][10]; int shapes[10][10]; int colors[10][10]; set 
      
        col_c[10]; set 
       
         col_s[10]; int n; int cnt = 0; int dfs(int x, int y ) { int f = 0; for ( int i = y; i <= n; i++ ) { swap( shapes[x][i], shapes[x][y]); if ( col_s[y].count( shapes[x][y]) == 0 ) { col_s[y].insert(shapes[x][y] ); for ( int j = y; j <= n;j++ ) { swap( colors[x][j],colors[x][y] ); if ( col_c[y].count(colors[x][y] ) == 0 ) { col_c[y].insert(colors[x][y] ); if (!used[shapes[x][y]][colors[x][y]] ) { used[shapes[x][y]][colors[x][y]] = 1; f = 1; if ( x== n && y == n ) { ++cnt; }else { if( y == n ) { dfs(x + 1, 1 ); }else { dfs(x, y + 1 ); } } used[shapes[x][y]][colors[x][y]]= 0; } col_c[y].erase(colors[x][y] ); } swap( colors[x][j],colors[x][y] ); } col_s[y].erase(shapes[x][y] ); } swap( shapes[x][i], shapes[x][y]); } return(f); } int main() { cin >> n; for ( int x = 1; x <= 9; x++ ) for ( int i = 1; i <= 9; i++ ) { shapes[x][i] = colors[x][i]= i; } dfs( 1, 1 ); cout << "答案:" << cnt<< endl; return(0); } 
        
       
      
     
    
  

运行结果:




版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/226451.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午10:52
下一篇 2026年3月16日 下午10:53


相关推荐

  • Redis-GEO

    Redis-GEO

    2021年11月3日
    53
  • 静态测试方法

    静态测试方法本文讨论人工静态测试方法和自动静态测试方法 来帮你理解研发流程上是如何保证代码质量的 以及如何搭建自己的自动静态代码扫描方案 并且应用到项目的日常开发工作中去 人工静态方法人工静态方法检查代码错误 主要有代码走查 结对编程 以及同行评审这三种手段 代码走查代码走查 CodeReview 是由开发人员检查自己的代码 尽可能多地发现各类潜在错误 但是 由于个人能力的差异 以及开发人员的 思维惯性 很多错误并不能在这个阶段被及时发现 结对编程结对编程 PairProgramm

    2026年3月20日
    1
  • springboot和springframework以及jdk版本的对应关系

    springboot和springframework以及jdk版本的对应关系Springboot版本 SpringFramework jdk版本 maven版本 1.2.0版本之前 6 3.0 1.2.0 4.1.3+ 6 3.2+ 1.2.1 4.1.3+ 7 3.2+ 1.2.3 4.1.5+ 7 3.2+ 1.3.4 4.2.6+ 7 3.2+ 1.3.6 4.2.7+ 7 3.2+ 1.3.7 4.2.

    2022年5月16日
    260
  • HorizontalScrollView扩展总结

    HorizontalScrollView扩展总结ScrollView相信大家都已经比较熟悉了,它是支持垂直滚动的,在开发中经常使用到,与垂直滚动相对的就是水平滚动HorizontalScrollView,有时我们在进行页面切换的时候也会用到HorizontalScrollView。通过查看源码比较发现ScrollView和HorizontalScrollView有好多相同的方法。在说扩展之前,我先说一下HorizontalScrollVie

    2022年7月14日
    28
  • 腾讯文档 MCP 使用指南

    腾讯文档 MCP 使用指南

    2026年3月15日
    28
  • Gitblit服务器搭建

    Gitblit服务器搭建Gitblit服务器搭建

    2022年4月23日
    44

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号