• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
dwtfukgv
博客园    首页    新随笔    联系   管理    订阅  订阅
CodeForces 288B Polo the Penguin and Houses (暴力或都快速幂)

题意:给定 n 和k,n 表示有n个房子,然后每个有一个编号,一只鹅要从一个房间中开始走,下一站就是房间的编号,现在要你求出有多少种方法编号并满足下面的要求:

1.如果从1-k房间开始走,一定能直到 1。

2.如果从k+1到n 开始走,一定走不到 1.

3.如果从 1 开始走,那么一定能回到1,并且走过房间数不为0.

析:这个题,当时想了好久,其实并不难,当时是暴力过的,一看 k 最大才是8,那么应该不会TLE,然后就暴力了。首先这前 k 个数和后面的数,完全没有关系,

后面就是 n-k的 n-k次方,关键是前面,我们可以一个一个的试,并判断会不会成立,用DFS即可。

 这个题可以用快速幂来做。

代码如下:

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int maxn = 1000000 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
const int dr[] = {0, 0, 1, -1};
const int dc[] = {1, -1, 0, 0};
int cnt, k;
int a[100];
set<int> ss;

bool judge(int u, int rt){
    if(a[u] == 1)  return true;
    if(a[u] != rt && u != a[u] && a[u] && !ss.count(u)){  ss.insert(u);  return judge(a[u], rt); }
    return false;
}

void dfs(int cur){
    if(cur == k+1){
        for(int i = 2; i <= k; ++i){
            ss.clear();
            if(!judge(i, i))  return ;
        }
        ++cnt;
        return ;
    }

    for(int i = 1; i <= k;++i){
        a[cur] = i;
        dfs(cur+1);
    }
    return ;
}

int qickpow(LL a, LL b){
    LL k = a;
    LL ans = 1;
    while(b){
        if(b & 1){
            ans = (ans * k) % mod;
        }

        k = (k * k) % mod;
        b >>= 1;
    }
    return (int) ans;
}

int main(){
    int ans;
    int n;
    scanf("%d %d", &n, &k);
    int t = n - k;
    ans = qickpow(n-k, n-k);
    cnt = 0;
    dfs(2);
    ans = (ans * k * cnt) % mod;
    cout << ans << endl;
    return 0;
}

 方法二:

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int maxn = 1000000 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
const int dr[] = {0, 0, 1, -1};
const int dc[] = {1, -1, 0, 0};
int cnt, k;

int qickpow(LL a, LL b){
    LL k = a;
    LL ans = 1;
    while(b){
        if(b & 1){
            ans = (ans * k) % mod;
        }

        k = (k * k) % mod;
        b >>= 1;
    }
    return (int) ans;
}

int main(){
    int ans;
    int n;
    scanf("%d %d", &n, &k);
    int t = n - k;
    ans = qickpow(n-k, n-k);
    cnt = 0;
    LL ans1 = qickpow(k, k-1);
    ans = (ans * ans1) % mod;
    cout << ans << endl;
    return 0;
}

 

posted on 2016-07-25 21:59  dwtfukgv  阅读(253)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3