2017. 圆周排列

单点时限: 2.0 sec

内存限制: 256 MB

相信排列大家很熟悉,从 3 个对象 a,b,c 中取 3 个的排列分别 abc, acb, bac, bca, cab 和 cba 6 个不同的方式 . 我们将从 n 个不同对象中取 r 个的排列个数计为 P(n,r)。而圆排列与排列的不同之处在于圆周排列头尾相邻,比如上例中 abc, bca, cab 就属于同一个圆周排列。我们定义从 n 个互不相同的对象中取 r 的圆排列数计为 Q(n,r). 已知 n,r 请你计算 Q(n,r).

输入格式
输入有多组 case,每个 case 一行, 是两个已空格隔开的整数 n 和 r( 0 <= r <= n ),且大小不超过 12。

输出格式
每个 case 输出一个整数,为 Q(n,r)。

样例
input
3 3
output
2

/*
思路:DFS全排列加验证超时了,没想到好的修枝剪叶
不过一开始猜想就是C(n,r)A(r-1),用DFS验证了几个是对的,果然提交通过了。
*/
#include<iostream>
#include<map>
#include<vector>
using namespace std;
int n,r;
/*
vector<int>v;
long long ans=0;
map<string,int>m;
bool visit[13]= {false};
int Index() {
	int Min=13;
	int index=0;
	for(int i = 0; i < v.size(); i++) {
		if(Min>v[i]) {
			index=i;
			Min=v[i];
		}
	}
	return index;
}
void dfs() {
	if(v.size()==r) {
		int q=Index();
		string s="";
		for(int i = q; i < r; i++)
			s+=to_string(v[i]);
		for(int i = 0; i < q; i++)
			s+=to_string(v[i]);
		if(m[s]==0) {
			ans++;
			m[s]=1;
		}
		return;
	}
	for(int i = 1; i <= n; i++) {
		if(visit[i]==false) {
			visit[i]=true;
			v.push_back(i);
			dfs();
			v.pop_back();
			visit[i]=false;
		}
	}
}
*/
long long C(int n,int r) {
	long long ans=1;
	for(int i = 0; i < r; i++) {
		ans*=(n-i);
	}
	return ans/r;
}
int main() {
	while(cin>>n>>r) {
		m.clear();
		ans=0;
		if(r==0)
			cout<<1<<endl;
		else {
		//	dfs();
			//cout<<ans<<endl;
			cout<<C(n,r)<<endl;
		}

	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40394960/article/details/105928445