H、Magic necklace

链接:https://ac.nowcoder.com/acm/contest/3570/H
来源:牛客网

题目描述

There was a magic necklace. The necklace is made of magical gems
numbered 1 through n. Unfortunately, the necklace was accidentally
broken yesterday. Every gem was scattered on the ground. Now you need
to restring the magic necklace with these n gems. In order to keep the
necklace magical, adjacent numbered gems cannot be placed next to each
other in the new necklace. Please output the number of ways to
successfully restring the necklace. If the relative positions of the
gems are the same, we think these are the same case. 输入描述: The first
line of the input contains one integer t — the number of test cases.(t
≤ 110) The next t lines contain test cases. Each line contains a
positive integer n(0 ≤ n ≤ 11)describing a test case. 输出描述: For each
test case, output a line containing an integer which indicates the
answer.

示例1
输入

3
1
2
5

输出

1
0
1

说明
在这里插入图片描述

The two pictures above show the same method.

思路如下

数据范围最大就到n = 11,dfs爆搜即可得到答案,由于题面是多组,需要预处理出答案以免TLE,还有这一题的去掉不符合题的情况也是很重要的

结题如下
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>

using namespace std;

int n,Ans,t;
int vis[105],ans[15];   //vis存放每种情况,ans存储1~11个数字对应的答案

void dfs(int cur,int fa,int cnt,int x)      //cnt表示递归了多少层、x表示要处理的数
{
    if(cnt == x && cur != 2)
    {
        Ans++;          //每种情况对应的方案数
        return;
    }
    else if(cnt == x) return;
    for(int i = 1;i <= x; i++)
    {
        if(vis[i]) continue;
        if(i == fa || i == cur) continue;
        if(abs(i - cur) == 1) continue;
        vis[i] = 1;
        dfs(i,cur,cnt + 1,x);
        vis[i] = 0;
    }
}

void init(int x){
    for(int i = 1;i <= x; i++) vis[i] = 0;
    vis[1] = 1;         //这里我们假定对应没个数字方n 我的都让方案以 1 开头(所以要把vis[1]进行标记),既然对应每个数字n方案的开头为1,则结尾就一定不能为2
    Ans = 0;
    dfs(1,0,1,x);
    ans[x] = Ans / 2;   //这里的得到的方案数为什么要除以2 ? ,这是因为方案中会有一半是重复的(还是举数字 n == 3这个例子来说吧:1 3 5 2 4 6 与 1 6 4 2 5 3 除了开头相同,其它的部分完全就是颠倒一下,这对与题意来说这两种情款完全是相同的),下面给出6的所有出现的方案Ans(包括重复的)
    /*
     n == 6 的所有Ans方案数
     1 3 5 2 4 6
     1 3 5 2 6 4
     1 3 6 4 2 5
     1 4 2 5 3 6
     1 4 2 6 3 5
     1 4 6 2 5 3
     1 5 2 4 6 3
     1 5 3 6 2 4
     1 6 3 5 2 4
     1 6 4 2 5 3
     */
}

int main()
{
    for(int i = 1;i <= 11; i++) init(i);

    ans[1] = 1;
    ans[0] = 0;

    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        printf("%d\n",ans[n]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值