hdu 5399(数学推理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5399

题意:

给你m个函数f1,f2,?,fm:{1,2,?,n}→{1,2,?,n}(即所有的x∈{1,2,?,n},对应的f(x)∈{1,2,?,n}),已知其中一部分函数的函数值,问你有多少种不同的组合使得所有的i(1≤i≤n),满足f1(f2(?fm(i)))=i

对于函数集f1,f2,?,fm and g1,g2,?,gm,当且仅当存在一个i(1≤i≤m),j(1≤j≤n),fi(j)≠gi(j),这样的组合才视为不同。其中输入-1表示f(x)可以等于任意一个值;

分析:

其实,仔细想想,你就会发现,此题的解跟-1的个数有关,当只有一个-1的时候,因为对应关系都已经决定了,所以只有1种可行解,而当你有两个-1时,其中一个函数的值可以根据另一个函数的改变而确定下来,故有n!种解。依此类推,当有k个-1时,(n!)^(k-1);

当然当k的值为0时有一种情况是输出1的要用dfs搞出来;

代码如下:

#include <iostream>
#include <map>
#include <cmath>
#include <string.h>
#include <cstdio>
using namespace std;
const int mod=1e9+7;
long long f[150];
long long quick_mod(long long a,long long b){
    long long ans=1;
    while(b){
        if(b&1)ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}//快速幂
int a[105][105];
bool vis[105];
int dfs(int t,int x)  {
    if(t==1)
        return a[t][x];
    return dfs(t-1,a[t][x]);
}//dfs求解判断
int main(){
    int n,m;
    f[1]=1;
    for(int i=2;i<150;i++)
    f[i]=f[i-1]*i%mod;
    while(scanf("%d%d",&n,&m)!=EOF){
        int k=0;
        bool flag=false;
        for(int i=1;i<=m;){
            int x;
            memset(vis,0,sizeof(vis));
            for(int j=1;j<=n;j++){
                scanf("%d",&x);
                if(x==-1){
                    k++;
                    goto Next;
                }
                a[i][j]=x;
                vis[x]=true;
            }
            for(int j=1;j<=n;j++)
            if(vis[j]==false)flag=true;
            Next:
            i++;
        }
        if(flag==true){
            cout<<0<<endl;
        }
        else if(k!=0){
            cout<<quick_mod(f[n],k-1)<<endl;
        }
        else{
            int i;
            for(i=1;i<=n;i++)
            if(dfs(m,i)!=i)
            break;
            if(i>n)
            puts("1");
            else
            puts("0");
        }
    }
    return 0;
}
时间: 2024-12-15 14:08:57

hdu 5399(数学推理)的相关文章

HDU 5399 数学 Too Simple

题意:有m个1~n的映射,而且对于任意的 i 满足 f1(f2(...fm(i))) = i 其中有些映射是知道的,有些是不知道的,问一共有多少种置换的组合. 分析: 首先这些置换一定是1~n的一个置换(也就是1~n的一个排列)才行,因为如果某两个数映射到同一个数的话,那么这个数往后无论怎么映射,这两个数最终映射的结果还是一样的. 如果所有的f都给出来的话,那么只要判断一下就行. 如果有一个置换不知道的话,这个置换是可以通过前后的置换计算出来的,所以只有唯一解. 如果有两个置换不知道的话,第一个

hdu 4961 数学杂题

http://acm.hdu.edu.cn/showproblem.php?pid=4961 先贴个O(nsqrtn)求1-n所有数的所有约数的代码: vector<int>divs[MAXN]; void caldivs() { for(int i=1;i<MAXN;i++) for(int j=i;j<MAXN;j+=i) divs[j].push_back(i); } 有了这个当时理下思路就可写了,但是重复数处理注意: 1.用一个数组vis[]  vis[i]=1表示i存在

Codeforces Round #224 (Div. 2) B 数学推理

挺有意思的一道题目,一开始发现了循环节,做了一下,发现许多小地方要补,比较繁琐,做了几个小时的无用功吧,但是循环节肯定可以只是我写搓了,后来又推了公式,发现可以的 首先当b<x的时候,c--,a--那么对于 a,c来说他们之间的差并没有减小,所以真正起到作用的是b>=x的时候,这个时候只有c--,但是答案要求的 是多少次,在b<x的时候 是要经过一定次数的  w-(x - b)来重新使得b>=x,所以第二部分对答案有影响,但是 设方程的话 就不需要多设一个未知数,因为 第一部分肯定

hdu 4811 数学 不难

http://acm.hdu.edu.cn/showproblem.php?pid=4811 因为看到ball[0]>=2 && ball[1]>=2 && ball[2]>=2  ans=(sum-6)*6+15    sum是三种颜色的球个数的和,然后就想到分类讨论,因为情况是可枚举的, 发现整数如果不加LL直接用%I64d打印会出问题 //#pragma comment(linker, "/STACK:102400000,102400000

HDU 5976 数学,逆元

1.HDU 5976 Detachment 2.题意:给一个正整数x,把x拆分成多个正整数的和,这些数不能有重复,要使这些数的积尽可能的大,输出积. 3.总结:首先我们要把数拆得尽可能小,这样积才会更大(当然不能拆1).所以容易想到是拆成2+3+...+n+s=x,先求出n即2+3+...+n<x<2+3+...+n+(n+1),然后将某个数向右平移s个单位变为n+1即可.注意:(1)预处理出前缀和,前缀积.(2)将某个数移到n+1,要除这个数再乘n+1,这里要用逆元,也要预处理出来. #in

*HDU 2451 数学

Simple Addition Expression Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1723    Accepted Submission(s): 675 Problem Description A luxury yacht with 100 passengers on board is sailing on the s

[ An Ac a Day ^_^ ] hdu 4565 数学推导+矩阵快速幂

从今天开始就有各站网络赛了 今天是ccpc全国赛的网络赛 希望一切顺利 可以去一次吉大 希望还能去一次大连 题意: 很明确是让你求Sn=[a+sqrt(b)^n]%m 思路: 一开始以为是水题 暴力了一发没过 上网看了一下才知道是快速幂 而且特征方程的推导简直精妙 尤其是共轭相抵消的构造 真的是太看能力了 (下图转自某大神博客) 特征方程是C^2=-2*a*C+(a*a-b) 然后用快速幂求解 临时学了下矩阵快速幂 从这道题能看出来 弄ACM真的要数学好 这不是学校认知的高数 线代 概率分数 而

hdu 4506(数学,循环节+快速幂)

小明系列故事——师兄帮帮忙 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 5427    Accepted Submission(s): 1461 Problem Description 小明自从告别了ACM/ICPC之后,就开始潜心研究数学问题了,一则可以为接下来的考研做准备,再者可以借此机会帮助一些同学,尤其是漂亮的师妹.这 不,班

hdu 4432 数学杂题

http://acm.hdu.edu.cn/showproblem.php?pid=4432 6分钟写的代码,一上午去调试,, 哎,一则题目没看懂就去写了,二则,哎,,恶心了,在坚持几天然后ACM退役,想当初一直想着regional拿奖,然后在保研的时候有个更漂亮的简历,卧槽,但是,其实喜欢的是静下心,把一块知识好好弄懂,看着自己一点点由不会到会,由不熟到熟练,而且在这个过程中总结一些思考问题的方法,能把这种思维应用于其他 但是----唉,急功近利式地学,老想着快,一没思路就去看题解,然后平均每