zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    php date 时间差
    array_merge 和 + 号的的区别
    apache 添加https后导致http无法访问
    php 获取url
    TP5 事务处理
    LeetCode 每日一题 (盛最多水的容器)
    LeetCode 每日一题 (字符串转换整数 (atoi))
    LeetCode 每日一题(5. 最长回文子串)
    LeetCode 每日一题 (3 无重复字符的最长子串)
    LeetCode 每日一题 (两数相加)
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5705477.html
Copyright © 2011-2022 走看看