zoukankan      html  css  js  c++  java
  • 找规律 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;//比题目多了一百行。。。
    }

  • 相关阅读:
    VUE第一个项目怎么读懂
    Excel催化剂开源第33波-Quick Bible For PPT插件项目全代码开源
    [iOS基础控件
    awk支持多个记录分隔符的写法
    关于awk中NR、FNR、NF、$NF、FS、OFS的说明
    测试开发CICD——Docker——docker安装nginx
    测试开发CICD——Docker——docker安装python3.5
    测试开发CICD——Docker——docker安装tomcat
    测试开发CICD——Docker——docker安装redis
    测试开发CICD——Docker——docker安装mysql
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632724.html
Copyright © 2011-2022 走看看