CF1391C Cyclic Permutations(思维,找规律)

36 篇文章 0 订阅
6 篇文章 0 订阅

题目链接

题目大意

在这里插入图片描述

思路

通过找规律发现,只有当一个排列中的一个数的两边都有1个比他大的数时才可能有环,比如说312,1432,如果没有,就不可能有环,比如1234。
然后打表,发现,
n = 3, 有2种,
n = 4, 有16种,
n = 5, 有104种,
n = 6, 有688种,

n = 3, 共有6种, 6 - 2 = 4 = 2 3 − 1 2^{3-1} 231
n = 4, 共有24种,24 - 16 = 8 = 2 4 − 1 2^{4-1} 241
n = 5, 共有120种,120 - 104 = 16 = 2 5 − 1 2^{5-1} 251
n = 6, 共有720种,720 - 688 = 32 = 2 6 − 1 2^{6-1} 261

我们又知道,一个数所有的排列有n!种,有环的排列方式的总数就是 n ! − 2 n − 1 n! - 2^{n-1} n!2n1

代码

#include<bits/stdc++.h> 
#define int long long
const int mod = 1e9 + 7;
using namespace std;
signed main()
{
	int n;
	cin >> n;
	int ans = 1;
	for (int i = 1; i <= n; i ++ )
	{
		ans *= i;
		ans %= mod;
	}
	int mm = 1;
	for (int i = 2; i <= n; i ++ )
	{
		mm *= 2;
		mm %= mod;
	}
	ans -= mm;
	ans %= mod;
	ans = (ans + mod) % mod; //因为之前有 - ,所以要先加模数,防止有负数
	cout << ans;
	return 0;
}


//打表找规律 
//#include<bits/stdc++.h> 
//#define int long long
//using namespace std;
//signed main()
//{
//	int n;
//	cin >> n;
//	int a[n + 10];
//	for (int i = 1; i <= n; i ++ )
//	{
//		a[i] = i;
//	}
//	int cnt=0;
//	do{
//		for (int i = 1; i <= n; i ++ )
//		{
//			int ans = 0;
//			for (int j = i - 1; j >= 1; j -- )
//			{
//				if (a[i] < a[j])
//				{
//					ans ++;
//					break;
//				}
//			}
//			for (int j = i + 1; j <= n; j ++ )
//			{
//				if (a[i] < a[j])
//				{
//					ans ++;
//					break;
//				}
//			}
//			if (ans == 2) 
//			{
//				cnt ++;
				cout << cnt;
//				cnt %= (int)1e9+7;
//				break;
//				for (int j = 1; j <= n; j ++ )
//				{
//					cout << a[i] << " ";
//				}
//				cout << endl;
//			}
//		}
//	}while(next_permutation(a + 1, a + 1 + n));
//	cout << cnt << endl;
//	return 0;
//}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值