找规律 permutation

    蛮不好想的,但实现极端容易。

   这道题第一步得读明白题,才能找到规律。首先每个循环得是标准循环,而且每个循环所有值之间必须挨着(不然将循环重新排序后顺序就会改变)

   好,读明白题后,根据筛选原理,打个表,找规律。。(打表程序顶仨题解)

   我把5的贴上(太大的没敢贴)

1 2 3 4 5


1 2 3 5 4


1 2 4 3 5


1 3 2 4 5

1 3 2 5 4


2 1 3 4 5

2 1 3 5 4

2 1 4 3 5 

     按此方式分开,会很想fibonaci。0位的是不改变的,之后动第一位,动第二位,动第三位,动第三位+第一位。从这里开始,就有从新开始开始了一个新的fibo循环,正好符合fibo的特性。

     因此,就用这种方法一直减k,并标记那几位被调转了位置。这里还要解释一下。n-1位与n位换后就被固定住,不再换了,打下标记即可。说白了就是fibo减到第几位,k比他小了,那么当前位就是要换的位。

     程序

    

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
int n,a[100],v[100];
ll k,f[100];
int main()
{
	scanf("%d%lld",&n,&k);
	f[0]=f[1]=f[2]=1;
	for(int i=3;i<=n;i++)f[i]=f[i-1]+f[i-2];
	for(int i=1;i<=n;i++)a[i]=i;
	while(k>1)
	{
		int i=0;
		while(k>f[i])k-=f[i],i++;
		v[n-i+1]=v[n-i]=1;
	}
	for(int i=1;i<n;i++)
	   if(v[i]&&v[i+1])
	      v[i]=v[i+1]=0,swap(a[i],a[i+1]);
	for(int i=1;i<=n;i++)printf("%d ",a[i]);//别笑就二十七行。。。
}
    然后,,打表的程序

  

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<string>
#include<cmath>
using namespace std;
int n;
long long k;
struct no{
	int a[80];
	long long js;
	bool friend operator > (no a,no b)
	{
		return a.js>b.js;
	}
};
int px(int x,int y)
{
	return x>y;
}
struct nod{
	int a[80];
	int zz;
	bool friend operator > (nod a,nod b)
	{
		return a.a[1]>b.a[1];
	}
};
priority_queue<no,vector<no>,greater<no > > q1;
bool us[80];
int a[80];
void dfs(int jj){
	if(jj==n)
	{
		priority_queue<nod,vector<nod>, greater<nod > > q2;
		bool fw[80];
		memset(fw,0,sizeof(fw));
		for(int i=1;i<=n;i++)
		{
			if(!fw[i])
			{
				int be=i;
				bool yxx=1;
				nod x;
				x.zz=0;
				memset(x.a,0,sizeof(x.a));
				for(int j=i;;j=a[j])
				{
					if(fw[j]) break;
					fw[j]=1;
					x.zz++;
					x.a[x.zz]=j;
				}
				sort(x.a+1,x.a+x.zz+1,px);
				q2.push(x);
			}
		}
		int jss=1;
		bool yxx=1;
		while(!q2.empty())
		{
			nod x=q2.top();
			q2.pop();
			//jss++;
			for(int i=1;i<=x.zz;i++)
			{
				if(a[jss]!=x.a[i])
				{
					yxx=0;
					break;
				}
				jss++;
			}
		}
		if(!yxx)return;
		
		long long sum=0;
		for(int i=1;i<=n;i++)
		{
			sum=sum*2+a[i];
		}
		no st;
		st.js=sum;
		memcpy(st.a,a,sizeof(a));
		q1.push(st);
		return;
	}
	bool uu[80];
	memcpy(uu,us,sizeof(us));
	int aa[80];
	memcpy(aa,a,sizeof(aa));
	int jjj=jj;
	bool yx=1;
	for(int i=1;i<=n;i++)
	{
		if(!us[i])
		{
			yx=0;
			us[i]=1;
			jj++;
			a[jj]=i;
			dfs(jj);
			memcpy(us,uu,sizeof(uu));
			memcpy(a,aa,sizeof(aa));
			jj=jjj;
		}
	}
}
int main(){
	freopen("fuck5.out","w",stdout);
	scanf("%d%lld",&n,&k);
	dfs(0);
	int js=0;
	while(!q1.empty())
	{
		js++;
		for(int i=1;i<=n;i++)
			cout<<q1.top().a[i]<<' ';
		cout<<endl;
		q1.pop();
	}
	return 0;//比题目多了一百行。。。
}

posted @ 2017-10-06 20:19  Hzoi_QTY  阅读(173)  评论(0编辑  收藏  举报