一点经验:从五星填数中所学到的

背景:
嗯~,这道题其实是我在学暴力的时候看到的,嗯,没错,就是学习暴力。没学的时候感觉这种东西肯定不用学呀,接触之后才发现自己原来是个连暴力都不会的菜鸡,其实这个题中也有好多我原来不知道或没有想到的用法。
好了,言归正传。

题目大意:
在这里插入图片描述
图1
在这里插入图片描述
图2

主要想法
做完之后还是对比了一下某份答案,虽然思路上差不多,但从代码实现感觉还是有点不一样,也各有千秋,就在这里一并介绍了吧。
思路其实还是比较直接的,就是先给每一个空编号(见图2),接着把每一种合法的方法都表示出来,然后再一个一个检验是否满足条件,然后就可以得出答案了。因为旋转的关系结果要除5,而因为对称也要除2,两者互不影响,所以结果总共要除10。

	先展示一下我自己的代码:(5行全部相加,每一个空都被算了两次,总和为120,分到每个为24)
#include<bits/stdc++.h>

using namespace std;

int main()
{
    int b,c=0,a[10]={1,2,3,4,5,6,8,9,10,12};
    do
    {
        b=0;
        if(a[1]+a[2]+a[3]+a[4]==24)b++;
        if(a[4]+a[6]+a[7]+a[8]==24)b++;
        if(a[0]+a[2]+a[5]+a[8]==24)b++;
        if(a[0]+a[3]+a[6]+a[9]==24)b++;
        if(a[1]+a[7]+a[5]+a[9]==24)b++;
        if(b==5)c++;
    }while(next_permutation(a,a+10));
    cout<<c/10<<endl;
}

两个因为思路相同就不展示它的了。仅展示两者不同之处。

首先,是它对于每一行的定义不同,它用到了宏替换,这个东西其实我知道,只是一般都不会想到,只是在定义大数的时候用一下,没有考虑到它更接地气的价值。

#define A (star[1]+star[3]+star[6]+star[9]);
#define B (star[1]+star[4]+star[8]+star[10]);
#define C (star[2]+star[3]+star[4]+star[5]);
#define D (star[2]+star[6]+star[7]+star[10]);
#define E (star[5]+star[7]+star[8]+star[9]);

其次是它直接表示了这个全排列,让我也知道了一般全排列的实现方法(这里展示的是计数,而非直接解答)。
最后就是它宏定义了一个函数,今天真是颠覆了我对宏代换的认识。/笑哭!!!

int star[]={0,1,2,3,4,5,6,8,9,10,12};   //0不用
#define Swap(a,b) {int temp = a; a = b; b = temp;}  //交换
int num=0;     //统计全排列的个数,验证是不是3628800
int Perm(int begin,int end)
{
    int i;
    if(begin == end)    // 结束,输出一个全排列
         num++;  //统计全排列的个数;
    else
         for(i = begin;i <= end;i++)
         {
      	Swap(star[begin],star[i]);//交换位置,逐步前提
      	Perm(begin+1,end);
      	Swap(star[begin],star[i]);//将位置还回去,对下一次排列负责
        }
}
int main()
{   Perm(1,10);  //求从第1个数到第10个数的全排列。
    cout<<num<<"\n"; //打印出排列总数,应该是3628800。
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值