一个搬运

屏幕解锁

题目背景

\(L\)得到了一个手机,手机的解锁方式是画出正确的图案,但是他不知道怎么解锁,由于某种特殊的原因,他知道了该画几个点

题目描述

给你一个\(n\),表示该画几个点,求出小\(L\)得尝试几次才能把手机解锁。

输入输出格式

输入格式:

输入一个\(n\),表示小\(L\)得画几个点

\(1 \leq n \leq 9\)

输出格式:

求出小\(L\)得尝试的次数

输入输出样例

输入样例#1

4

输出样例#1

1624

鬼知道我为什么又把题面打了一遍

看到这题面的第一眼

我首先想到了排列

然而

根据手机解锁的特性

有些点在某些情况是不能直接连上的

于是

我就想到了搜索

因为我不会广搜

所以我就打了深搜

#include<bits/stdc++.h>
#define ll long long
#define C getchar()
#define Violet inline
using namespace std;
Violet int read()
{
    int x=0;bool l=1;char c=C;
    for (;c<'0'||c>'9';c=C) if (c=='-') l=0;
    for (;c>='0'&&c<='9';c=C) x=(x<<3)+(x<<1)+c-48;
    return l?x:-x;
}
int n;
bool f[10];
int lin[10]={0,1,1,1,2,2,2,3,3,3};
ll ans;
Violet void dfs(int p,int now)//位于第p个点 已经连了now个点
{
    if(now==n)//已经连了n个点
    {
        ans++;
        return;
    }
    for(register int i=1;i<=9;i++)
    {
        if(f[i])										continue;//已经连了这个点
        int temp=abs(p-i);
        if(temp==6)/*位于同一列且中间有个点*/ if(!f[(i+p)>>1])/*中间这个点没连过*/					continue;//不能连
        if(temp==2) if(lin[p]==lin[i]) if(!f[(i+p)>>1])	continue;//同一行且中间隔了一个没连过的点
        if(temp==8) if(!f[5])							continue;//简单易懂
        if((i==3 && p==7) || (i==7 && p==3)) if(!f[5])	continue;//简单易懂不解释
        f[i]=1;
        dfs(i,now+1);//深搜
        f[i]=0;//回溯
    }
}
int main()
{
    n=read();
    for(int i=1;i<=9;i++)
    {
        f[i]=1;
        dfs(i,1);
        f[i]=0;
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/tjj233233/p/12897205.html