牛客月赛40(解题报告)

目录

A-数字游戏

题目:

​ 

思路分析:

代码实现:

B-跳跳跳

题目:​

思路分析:

代码实现:

C-数字匹配

题目:

思路分析:

代码实现:

D-优美的字符串

题目:

思路分析:

代码实现:

E-分组

题目:

思路分析:

代码实现:

F-过桥

题目:

思路分析:

代码实现:

G-空调遥控

题目:

思路分析:

代码实现:

I- 体操队形

题目:

思路分析:

代码实现:


A-数字游戏

题目:

 

思路分析:

这道题好玄学!(原来是我眼瞎了 要用快读和cout别用小心!

然后计算位运算的模拟操作了

最后一位取反直接^就行

然后计数1的个数可以拿lowbit来操作 lowbit的功能是取这个数二进制下最后一个1以及后面0的全部

在计数的同时可以找到第一位1方便之后为偶数的操作

代码实现:

/*
*@Author:   GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
/*
 *                                                     __----~~~~~~~~~~~------___
 *                                    .  .   ~~//====......          __--~ ~~
 *                    -.            \_|//     |||\\  ~~~~~~::::... /~
 *                 ___-==_       _-~o~  \/    |||  \\            _/~~-
 *         __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *     _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *   .~       .~       |   \\ -_    /  /-   /   ||      \   /
 *  /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 *  |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *           '         ~-|      /|    |-~\~~       __--~~
 *                       |-~~-_/ |    |   ~\_   _-~            /\
 *                            /  \     \__   \/~                \__
 *                        _--~ _/ | .-~~____--~-/                  ~~==.
 *                       ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                  -_     ~\      ~~---l__i__i__i--~~_/
 *                                  _-~-__   ~)  \--______________--~~
 *                                //.-~~~-~_--~- |-------~~~~~~~~
 *                                       //.-~~~--\
 *                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *                               神兽保佑            永无BUG
 */

int lowbit(int x){
    return x&-x;
}
int x,n;
int main(){
    
    scanf("%d",&n);
    while (n--) {
        
        scanf("%d",&x);
        int ans=0;
        while (x) {
            int a1=x;
            int num=0;
            int a2=0;
            while (a1) {
                if(a1==lowbit(a1)) a2=lowbit(a1);
                num++;
                a1-=lowbit(a1);
            }
            if(num&1) {
                x^=1;
            }
            else{
                x-=a2;
            }
            ans++;
        }
        printf("%d\n", ans);
    }
}

B-跳跳跳

题目:

思路分析:

一个区间DP的题目:

状态转移方程是: f[l][r]=max(dp(l+1,r)+len*a[l],dp(l,r-1)+len*a[r]); 

len是区间长度 通过记忆化好实现

然后枚举起点计算最大值就行

代码实现:

const int MAX=4010;
int n;
int a[MAX];
ll f[MAX][MAX];
int dp(int l,int r){
    if(f[l][r]) return f[l][r];
    if(l==r) return a[l];
    int len=r-l+1;
    return f[l][r]=max(dp(l+1,r)+len*a[l],dp(l,r-1)+len*a[r]);
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        a[i+n]=a[i];
    }
    ll ans=0;
    for(int i=1;i<=n;i++){
        ans=max(ans,dp(i,i+n-1));
    }
    cout<<ans;
}

C-数字匹配

题目:

思路分析:

用了类似hash的思想

i和j有>=k的重合位那么就一定存在k位的重合

我们枚举i的每k位的数字放入桶中

然后枚举j的每k位数字在桶中查找

如果找到的话++

代码实现:

/*
*@Author:   GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
/*
 *                                                     __----~~~~~~~~~~~------___
 *                                    .  .   ~~//====......          __--~ ~~
 *                    -.            \_|//     |||\\  ~~~~~~::::... /~
 *                 ___-==_       _-~o~  \/    |||  \\            _/~~-
 *         __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *     _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *   .~       .~       |   \\ -_    /  /-   /   ||      \   /
 *  /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 *  |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *           '         ~-|      /|    |-~\~~       __--~~
 *                       |-~~-_/ |    |   ~\_   _-~            /\
 *                            /  \     \__   \/~                \__
 *                        _--~ _/ | .-~~____--~-/                  ~~==.
 *                       ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                  -_     ~\      ~~---l__i__i__i--~~_/
 *                                  _-~-__   ~)  \--______________--~~
 *                                //.-~~~-~_--~- |-------~~~~~~~~
 *                                       //.-~~~--\
 *                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *                               神兽保佑            永无BUG
 */


int n,k;
const int MAX=114514;
int Hash[MAX];
int ans;
int a[MAX];
void insert(int x){
    int pos=0;
    while (x) {
        a[++pos]=x&1;
        x>>=1;
    }
    int s=0;
    for(int i=1;i<=k;i++){
        s=s*2+a[i];
    }
    Hash[s]=1;
    for(int i=k+1;i<=pos;i++){
//        s=2*(s-a[i-k]*(1ll<<(k-1)))+a[i];
        s=2*(s-(1ll<<(k-1))*a[i-k])+a[i];
        Hash[s]=1;
    }
}
void query(int x){
    int pos=0;
    while (x) {
        a[++pos]=x&1;
        x>>=1;
    }
    int s=0;
    for(int i=1;i<=k;i++){
        s=s*2+a[i];
    }
    if(Hash[s]){
        ans++;
        return;
    }
    for(int i=k+1;i<=pos;i++){
        s=2*(s-(1ll<<(k-1))*a[i-k])+a[i];
        if(Hash[s]){
            ans++;
            return;
        }
    }
}
void clear(int x) {
    int pos=0;
    while (x) {
        a[++pos]=x&1;
        x>>=1;
    }
    int s=0;
    for(int i=1;i<=k;i++){
        s=s*2+a[i];
    }
    Hash[s]=0;
    for(int i =k+1;i<=pos;i++) {
        s=2*(s-(1ll<<(k-1))*a[i-k])+a[i];
        Hash[s] = 0;
    }
//    mms(Hash,0);
}
int main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            int ws1 = log2(i) + 1, ws2 = log2(j) + 1;
             if(ws1 < k || ws2 < k) {
                continue;
            }
            insert(i);
            query(j);
            clear(i);
        }
    }
    cout<<ans;
}

D-优美的字符串

题目:

思路分析:

就是找相邻不同的间隔数 

代码实现:

/*
*@Author:   GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
/*
 *                                                     __----~~~~~~~~~~~------___
 *                                    .  .   ~~//====......          __--~ ~~
 *                    -.            \_|//     |||\\  ~~~~~~::::... /~
 *                 ___-==_       _-~o~  \/    |||  \\            _/~~-
 *         __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *     _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *   .~       .~       |   \\ -_    /  /-   /   ||      \   /
 *  /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 *  |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *           '         ~-|      /|    |-~\~~       __--~~
 *                       |-~~-_/ |    |   ~\_   _-~            /\
 *                            /  \     \__   \/~                \__
 *                        _--~ _/ | .-~~____--~-/                  ~~==.
 *                       ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                  -_     ~\      ~~---l__i__i__i--~~_/
 *                                  _-~-__   ~)  \--______________--~~
 *                                //.-~~~-~_--~- |-------~~~~~~~~
 *                                       //.-~~~--\
 *                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *                               神兽保佑            永无BUG
 */


const int MAX=10001;
int w(string s){
    int ans=0;
    for(int i=0;i<s.length()-1;i++){
        if(s[i]==s[i+1]){
            ans++;
        }
    }
    return  ans;
}
int main(){
    int n;
    cin>>n;
    while (n--) {
        string s;
        cin>>s;
        cout<<s.length()+w(s)<<endl;
    }
}

E-分组

题目:

思路分析:

最大的最小很容易想到二分

但是题目数据很小

直接枚举check也行

代码实现:

代码1:

const int MAX=100010;
int n,m;
int a[MAX];
map<int,int>mp;
vector<int>v;
int ch(int x){
    int ans=0;
    for(int i=0;i<v.size();i++){
        double y=x;
        ans+=ceil(mp[v[i]]/y);
    }
//    cout<<"ans= "<<ans<<endl;
    if(ans>m) return 0;
    return 1;
}
int main(){
    cin>>n>>m;
    set<int>st;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        if(st.count(a[i])==0){
            st.insert(a[i]);
            v.push_back(a[i]);
        }
        mp[a[i]]++;
    }
//    cout<<mp[2]<<endl;
//    cout<<mp[3]<<endl;
    if(st.size()>m){
        cout<<-1;
        return 0;
    }

    for(int i=1;i<=n;i++){
        if(ch(i)){
            cout<<i;
            return 0;
        }
    }
    cout<<-1;
}

代码2(二分)

/*
*@Author:   GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
/*
 *                                                     __----~~~~~~~~~~~------___
 *                                    .  .   ~~//====......          __--~ ~~
 *                    -.            \_|//     |||\\  ~~~~~~::::... /~
 *                 ___-==_       _-~o~  \/    |||  \\            _/~~-
 *         __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *     _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *   .~       .~       |   \\ -_    /  /-   /   ||      \   /
 *  /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 *  |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *           '         ~-|      /|    |-~\~~       __--~~
 *                       |-~~-_/ |    |   ~\_   _-~            /\
 *                            /  \     \__   \/~                \__
 *                        _--~ _/ | .-~~____--~-/                  ~~==.
 *                       ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                  -_     ~\      ~~---l__i__i__i--~~_/
 *                                  _-~-__   ~)  \--______________--~~
 *                                //.-~~~-~_--~- |-------~~~~~~~~
 *                                       //.-~~~--\
 *                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *                               神兽保佑            永无BUG
 */

const int MAX=100010;
int n,m;
int a[MAX];
int ch(int x){
    int ans=0;
    for(int i=1;i<=MAX;i++){
        if(a[i]){
            ans+=(a[i]-1)/x+1;
        }
    }
    return ans<=m;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        a[x]++;
    }
    int l=1;
    int r=n;
    while (l+1<r) {
        int mid=(l+r)>>1;
        if(ch(mid)){
            r=mid;
        }
        else l=mid;
    }
    if(!ch(r)) r=-1;
    cout<<r;
}

F-过桥

题目:

思路分析:

这道题可以理解为dp模型也可以理解为最短路模型

代码实现:

代码1dp

/*
*@Author:   GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
/*
 *                                                     __----~~~~~~~~~~~------___
 *                                    .  .   ~~//====......          __--~ ~~
 *                    -.            \_|//     |||\\  ~~~~~~::::... /~
 *                 ___-==_       _-~o~  \/    |||  \\            _/~~-
 *         __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *     _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *   .~       .~       |   \\ -_    /  /-   /   ||      \   /
 *  /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 *  |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *           '         ~-|      /|    |-~\~~       __--~~
 *                       |-~~-_/ |    |   ~\_   _-~            /\
 *                            /  \     \__   \/~                \__
 *                        _--~ _/ | .-~~____--~-/                  ~~==.
 *                       ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                  -_     ~\      ~~---l__i__i__i--~~_/
 *                                  _-~-__   ~)  \--______________--~~
 *                                //.-~~~-~_--~- |-------~~~~~~~~
 *                                       //.-~~~--\
 *                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *                               神兽保佑            永无BUG
 */


const int MAX=100001;
int n,m;
int a[MAX];
int dp[MAX];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    mms(dp,INF);
    dp[1]=0;
    
    for(int i=1;i<=n;i++){
        if(a[i]>0){
            for(int j=i+1;j<=a[i]+i;j++){
                dp[j]=min(dp[j],dp[i]+1);
            }
        }
        else{
            for(int j=i+a[i];j<=i-1;j++){
                dp[j]=min(dp[j],dp[i]+1);
            }
        }
    }
    if(dp[n]>=INF) cout<<-1;
    else cout<<dp[n];
    
    
}

代码2最短路

/*
*@Author:   GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
/*
 *                                                     __----~~~~~~~~~~~------___
 *                                    .  .   ~~//====......          __--~ ~~
 *                    -.            \_|//     |||\\  ~~~~~~::::... /~
 *                 ___-==_       _-~o~  \/    |||  \\            _/~~-
 *         __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *     _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *   .~       .~       |   \\ -_    /  /-   /   ||      \   /
 *  /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 *  |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *           '         ~-|      /|    |-~\~~       __--~~
 *                       |-~~-_/ |    |   ~\_   _-~            /\
 *                            /  \     \__   \/~                \__
 *                        _--~ _/ | .-~~____--~-/                  ~~==.
 *                       ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                  -_     ~\      ~~---l__i__i__i--~~_/
 *                                  _-~-__   ~)  \--______________--~~
 *                                //.-~~~-~_--~- |-------~~~~~~~~
 *                                       //.-~~~--\
 *                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *                               神兽保佑            永无BUG
 */


#define N 2005
using namespace std;
struct edge {
    int v, nxt;
} e[N * N << 1];
int p[N], eid;
void init() {
    memset(p, -1, sizeof p);
    eid = 0;
}
void insert(int u, int v) {
    e[eid].v = v;
    e[eid].nxt = p[u];
    p[u] = eid ++;
}
int dis[N], n, a[N];
queue<int> q;
void bfs(int S) {
    memset(dis, -1, sizeof dis);
    dis[S] = 0; q.push(S);
    while(q.size()) {
        int u = q.front(); q.pop();
        for(int i = p[u]; i + 1; i = e[i].nxt) {
            int v = e[i].v;
            if(dis[v] == -1) {
                dis[v] = dis[u] + 1;
                q.push(v);
            }
        }
    }
}
int main() {
    init();
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) {
        scanf("%d", &a[i]);
        if(a[i] > 0) {
            for(int j = i + 1; j <= min(n, a[i] + i); j ++) {
                insert(j, i);
            }
        }
        if(a[i] < 0) {
            for(int j = 1; j <= max(1, i + a[i]); j ++) {
                insert(j, i);
            }
        }
    }
    bfs(n);
    printf("%d", dis[1]);
    return 0;
}

G-空调遥控

题目:

思路分析:

数据范围比较小 我们直接枚举k 然后预处理前缀和 找最大值就行 

或者用差分思想解决

代码实现:

/*
*@Author:   GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
/*
 *                                                     __----~~~~~~~~~~~------___
 *                                    .  .   ~~//====......          __--~ ~~
 *                    -.            \_|//     |||\\  ~~~~~~::::... /~
 *                 ___-==_       _-~o~  \/    |||  \\            _/~~-
 *         __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *     _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *   .~       .~       |   \\ -_    /  /-   /   ||      \   /
 *  /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 *  |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *           '         ~-|      /|    |-~\~~       __--~~
 *                       |-~~-_/ |    |   ~\_   _-~            /\
 *                            /  \     \__   \/~                \__
 *                        _--~ _/ | .-~~____--~-/                  ~~==.
 *                       ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                  -_     ~\      ~~---l__i__i__i--~~_/
 *                                  _-~-__   ~)  \--______________--~~
 *                                //.-~~~-~_--~- |-------~~~~~~~~
 *                                       //.-~~~--\
 *                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *                               神兽保佑            永无BUG
 */


const int MAX=1000000;
int a[MAX+10];
int n,p;
int main(){
    n=read();
    p=read();
    for(int i=1;i<=n;i++){
        int x;
        x=read();
        a[x]++;
    }
    for(int i=1;i<=MAX;i++){
        a[i]+=a[i-1];
    }
    int ans=0;
    for(int i=1;i<=MAX;i++){
        ans=max(ans,a[min(MAX,p+i)]-a[max(0,i-p-1)]);
    }
    cout<<ans;
}

代码2

/*
*@Author:   GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
/*
 *                                                     __----~~~~~~~~~~~------___
 *                                    .  .   ~~//====......          __--~ ~~
 *                    -.            \_|//     |||\\  ~~~~~~::::... /~
 *                 ___-==_       _-~o~  \/    |||  \\            _/~~-
 *         __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *     _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *   .~       .~       |   \\ -_    /  /-   /   ||      \   /
 *  /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 *  |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *           '         ~-|      /|    |-~\~~       __--~~
 *                       |-~~-_/ |    |   ~\_   _-~            /\
 *                            /  \     \__   \/~                \__
 *                        _--~ _/ | .-~~____--~-/                  ~~==.
 *                       ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                  -_     ~\      ~~---l__i__i__i--~~_/
 *                                  _-~-__   ~)  \--______________--~~
 *                                //.-~~~-~_--~- |-------~~~~~~~~
 *                                       //.-~~~--\
 *                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *                               神兽保佑            永无BUG
 */


const int MAX=2000210;
int n,p;
int a[MAX];
int main(){
    cin>>n>>p;
    for(int i=1;i<=n;i++)
    {
        int x;
        cin>>x;
        a[max(1,x-p)]++;
        a[x+p+1]--;
    }
    int ans=0;
    int now=0;
    for(int i=1;i<=MAX;i++){
        now+=a[i];
        ans=max(ans,now);
    }
    cout<<ans<<endl;
    
}

I- 体操队形

题目:

思路分析:

数据很小 我们可以直接枚举所有状态(全排列就行n!的复杂度 

然后check就行

思路2.状态压缩dp

思路3.暴搜

代码实现:

枚举:

/*
*@Author:   GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
/*
 *                                                     __----~~~~~~~~~~~------___
 *                                    .  .   ~~//====......          __--~ ~~
 *                    -.            \_|//     |||\\  ~~~~~~::::... /~
 *                 ___-==_       _-~o~  \/    |||  \\            _/~~-
 *         __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *     _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *   .~       .~       |   \\ -_    /  /-   /   ||      \   /
 *  /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 *  |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *           '         ~-|      /|    |-~\~~       __--~~
 *                       |-~~-_/ |    |   ~\_   _-~            /\
 *                            /  \     \__   \/~                \__
 *                        _--~ _/ | .-~~____--~-/                  ~~==.
 *                       ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                  -_     ~\      ~~---l__i__i__i--~~_/
 *                                  _-~-__   ~)  \--______________--~~
 *                                //.-~~~-~_--~- |-------~~~~~~~~
 *                                       //.-~~~--\
 *                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *                               神兽保佑            永无BUG
 */


const int MAX=12;
int a[MAX];
map<char,int>mp;
int ans;
void permutation(char *str,int length)
{
    sort(str,str+length);
    do
    {
//        for(int i=0; i<length; i++)
//        {
//            printf("%c ",str[i]);
//        }
//        printf("\n");
        for(int i=0;i<length;i++){
            mp[str[i]]=i;
        }
//        for(int i=0;i<length;i++){
//            cout<<str[i]<<"--"<<mp[str[i]]<<endl;
//        }
        int flag=1;
        for(int i=0;i<length;i++){
            if(a[i]!=i+1){
                if(mp[i+1+'0']>mp[a[i]+'0'])
                    flag=0;
            }
        }
        if(flag) ans++;
        
    }
    while(next_permutation(str,str+length));

}
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    char str[10];
    for(int i=0;i<n;i++){
        str[i]='1'+i;
    }
    
    
    permutation(str,n);
    cout<<ans;
    return 0;
}

爆搜

/*
*@Author:   GuoJinlong
*@Language: C++
*/
//#include <bits/stdc++.h>
/*
 *                                                     __----~~~~~~~~~~~------___
 *                                    .  .   ~~//====......          __--~ ~~
 *                    -.            \_|//     |||\\  ~~~~~~::::... /~
 *                 ___-==_       _-~o~  \/    |||  \\            _/~~-
 *         __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *     _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *   .~       .~       |   \\ -_    /  /-   /   ||      \   /
 *  /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 *  |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *           '         ~-|      /|    |-~\~~       __--~~
 *                       |-~~-_/ |    |   ~\_   _-~            /\
 *                            /  \     \__   \/~                \__
 *                        _--~ _/ | .-~~____--~-/                  ~~==.
 *                       ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                  -_     ~\      ~~---l__i__i__i--~~_/
 *                                  _-~-__   ~)  \--______________--~~
 *                                //.-~~~-~_--~- |-------~~~~~~~~
 *                                       //.-~~~--\
 *                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *                               神兽保佑            永无BUG
 */


const int MAX=15;
int vis[MAX];
int n;
int a[MAX];
int in[MAX];
int ans;
void dfs(int pos){
    if(pos==n){
        ans++;
        return;
    }
    for(int i=1;i<=n;i++){
        if(!vis[i]&&!in[i]){
            vis[i]=1;
            if(a[i]!=i) in[a[i]]--;
            dfs(pos+1);
            vis[i]=0;
            if(a[i]!=i) in[a[i]]++;
        }
    }
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        if(a[i]!=i) in[a[i]]++;
    }
    dfs(1);
    cout<<ans<<endl;
    
}

猜你喜欢

转载自blog.csdn.net/m0_57006708/article/details/121177339