屏幕解锁
题目背景
小(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
",ans);
return 0;
}