小G的城堡-找规律

小G的城堡

文件名 输入文件 输出文件 时间限制 空间限制
castle.pas/c/cpp castle.in castle.out 1s 128MB
题目描述
小 G 家有一座城堡。城堡里面有 n 个房间,每个房间上都写着一个数字 pi。
小 G 拉着几个小伙伴在城堡里面玩耍,他们约定,如果某个人当前站在 i 房间里
面,下一步这个人就会去 pi 房间,再下一步这个人去 ppi。
为了增加趣味性,小 G 想重新书写每个房间的 pi,以满足:
• 如果从编号 1 到 k 中的某个房间开始,按照规则走,必须能够走到 1 号房间。
特别地,如果从 1 号房间开始走,也要能够走回 1 号房间(至少走一步,如
果 p1 = 1,从 1 走到 1 也算合法)。
• 如果从编号大于 k 的某个房间开始,按照规则走,一定不能走到 1 号房间。
小 G 想知道,有多少种书写 pi 的方案,可以满足要求。
输入格式
输入文件一行两个数字 n, k,含义如题。
输出格式
输出文件一个数字,表示合法的方案数。答案对 109 + 7 取模。
样例输入 1
5 2
4
样例输出 1
54
样例输入 2
7 4
样例输出 2
1728
数据范围
对于 40% 的数据,1 ≤ n ≤ 8
对于 70% 的数据,1 ≤ n ≤ 105
对于 100% 的数据,1 ≤ n ≤ 1018
, 1 ≤ k ≤ min(8, n)。

看到这个数据范围,你就应该明白,得O(1),其实,爆搜前八项基本就能找出规律 ,根据题意,方案数=(1,k)×(k,n)
[k,n]的数只要是k~n的,随你怎么搞,所以方案数为n-k的(n-k)次方,前面的直接爆搜就OK了。

#include
using namespace std;
#define mod 1000000007
int n,k,a[10],ans;
bool vis[10];
void dfs(int now){
    if(now>k){

        for(int i=1;i<=k;i++){
        memset(vis,0,sizeof vis);
            int now=a[i];
            while(now!=1&&!vis[now]){
                vis[now]=1;
                now=a[now];
            }
            if(now!=1) return;
        }
       // for(int i=1;i<=k;i++) {
       // cout<
       // }
        //cout<
        ans++;
        return;
    }
    for(int i=1;i<=k;i++){
        a[now]=i;
        dfs(now+1);
    }
}
int quick(int x,int y,int p){
    int ret=1;
    while(y){
        if(y&1) ret=(ret*x)%p;
        y/=2;
        x=(x*x)%p;
    }
    return ret;
}
int main(){
//	freopen("castle,in","r",stdin);freopen("castle.out","w",stdout);
	scanf("%d%d",&n,&k);
	dfs(1);
	//int t=quick(n-k,n-k,mod);//
	printf("%d",ans*quick(n-k,n-k,mod));
	return 0;
}


你可能感兴趣的:(小G的城堡-找规律)