hdu5399(找规律。。。)
生活随笔
收集整理的這篇文章主要介紹了
hdu5399(找规律。。。)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題意:
一個有n個數(shù)字的集合,有m次映射(函數(shù)),-1代表我們不知道的映射,可以隨便安排,問經(jīng)過你的安排之后,有多少種會使得最后的所有的f[i]=i。
思路:
首先,我們要知道,如果-1有很多個,假如是nn個,那么,前nn-1個-1我們都可以隨便安排,因為最后一個-1一定可以把我們的映射變的合法,所以前nn-1個-1每個有n!種安排,所以有(n!)^(nn-1)種安排,而且如果m行中,某一行有重復的數(shù)字,那么一定輸出0。
代碼:
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std;int f[110][110]; const int MOD = 1000000007; int cal[110]; void prepare() {long long now = 1;cal[1] = 1;for (int i = 2; i < 105; i++) {now *= i;now %= MOD;cal[i] = (int)now;} }long long pow(long long a, long long i, long long n) {if (i == 0) {return 1 % n;}int temp = pow(a, i>>1, n)%n;temp = temp%n*temp%n;if (i & 1) {temp = (long long)temp * a % n;temp %= n;}return temp % n; }int check(int num[], int cnt) {int vis[200];memset(vis, 0, sizeof(vis));for (int i = 0; i < cnt; i++) {vis[num[i]] = 1;}for (int i = 1; i <= cnt; i++) {if (vis[i] == 0) {return 0;}}return 1; }int main() {int n, m;prepare();while (scanf("%d%d", &n, &m) != EOF) {int tot = 0;int tok = 0;for (int i = 0; i < m; i++) {int fir;scanf("%d", &fir);if (fir == -1) {tot++;f[i][0] = -1;}else {f[i][0] = fir;for (int j = 1; j < n; j++) {scanf("%d", &f[i][j]);}if (check(f[i], n) == 0) {tok = 1;}}}if (tok == 1) {puts("0");}else if (tot == 1) {puts("1");}else if (tot > 0) {long long ans = (long long)pow(cal[n] % MOD, tot-1, MOD);ans %= MOD;printf("%d\n", (int)ans);}else {int ok = 0;for (int i = 0; i < n; i++) {int now = f[m-1][i] - 1;for (int j = m - 2; j >= 0; j--) {now = f[j][now] - 1;}if (now != i) {ok = 1;break;}}if (ok) {puts("0");}else {puts("1");}}}return 0; }與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖
總結(jié)
以上是生活随笔為你收集整理的hdu5399(找规律。。。)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: uvalive5796(图论、桥、并查集
- 下一篇: hdu5399(模拟)