zoukankan      html  css  js  c++  java
  • 带分数(dfs,next_permutation)

    问题描述

    100 可以表示为带分数的形式:100 = 3 + 69258 / 714。

    还可以表示为:100 = 82 + 3546 / 197。

    注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。

    类似这样的带分数,100 有 11 种表示法。

    输入格式

    从标准输入读入一个正整数N (N<1000*1000)

    输出格式

    程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。

    注意:不要求输出每个表示,只统计有多少表示法!

    样例输入1
    100
    样例输出1
    11
    样例输入2
    105
    样例输出2
    6
    解法一:直接用c++里面求全排列的函数next_permutation,这样比较好理解,但用时比较长
    #include<iostream>
    #include <algorithm>
    using namespace std;
    
    int sum(int start,int end,int a[])
    {
        int i,sum=0;
        for(i=start; i<end; i++)
            sum=sum*10+a[i];
        return sum;
    }
    
    int main()
    {
        int m,aws=0,a[10];
        int i,j;
    
        scanf("%d",&m);
        for(i=0; i<9; i++)
            a[i]=i+1;
        do
        {
            for(i=1; i<10; i++)
            {
                int m1=sum(0,i,a);
                if(m1>=m)
                    continue;      //不满足条件直接跳过
                for(j=i+(10-i)/2; j<9; j++)      //从第一个数用过的数后开始
                {
                    int m2=sum(i,j,a);
                    int m3=sum(j,9,a);
                    if(m2%m3==0&&m==m1+m2/m3)
                    {
                        aws++;  //  统计符合条件的
                    }
                }
            }
        }
        while(next_permutation(a, a+9));  //枚举全排列
        printf("%d",aws);
        return 0;
    }
    

      其中next_permutation函数部分可以用dfs代替,代码如下:(关于用dfs实现全排列的思想请见链接:http://www.cnblogs.com/curo0119/p/8414195.html

    #include<cstdio>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    int flag[11]={0};
    int a[11];
    int ncount=0;
    int pp=0;
    int getSum(int start,int end,int a[])
    {
    	int sum=0;
    	for(int i=start;i<end;i++)
    	{
    		sum=sum*10+a[i];
    	}
    	return sum;
    }
    void Found(int a[],int n)
    {
    	int re1,re2,re3;
    	re1=0;
    	re2=0;
    	re3=0;
    	for(int i=1;i<10;i++)
    		{
    			re1=getSum(0,i,a);
    			if(re1>=n) continue;
    			for(int j=i+(10-i)/2;j<9;j++)
    			{
    				re2=getSum(i,j,a);
    				re3=getSum(j,9,a);
    				if(re2>re3&&re2%re3==0&&n==re1+re2/re3)
    				{
    					ncount++;
    				}
    			}
    		  }
    }
    void DFS(int start,int m)//对1~9进行全排列
    {
        int i;
        if(start==9)
            Found(a,m);  //每排好一个序列调用一次该函数,判断是否满足等式
        else
        {
         //排序列 for(i=1; i<10; i++) { if(!flag[i]) { a[start]=i; flag[i]=1; //标记是否用过 DFS(start+1,m);//选择好一位开始选下一位 flag[i]=0;//根据递归函数的压栈过程,把当前序列已经标记过的解除标记(从0到9全解除后再进入下一次序列的生成) } //当返回上一级的dfs的时候,会接着执行下面的语句,不会重复调用dfs了(函数的压栈过程) } } } int main() { int n; scanf("%d",&n); int i,j; int a[10]; for(i=0;i<9;i++) { a[i]=i+1; } DFS(0,n); printf("%d",ncount); return 0; }

      本文转载于:http://blog.csdn.net/zhangffyy/article/details/54952548

  • 相关阅读:
    Android开发环境下关于如何导出手机通讯录数据库【Written By KillerLegend】
    Win+R快速打开你的应用程序
    public void onItemClick(AdapterView arg0, View view, int position,long arg3)详解【整理自网络】
    Adapter的getView方法详解
    LayoutInflater中四种类型inflate方法的介绍
    程序员电脑桌面,哪一张触动了你?
    o​r​a​c​l​e​ ​O​D​B​C​配​置 图形界面
    C#String与string大小写的区别
    怎么使用FlashFXP上传网站
    C#操作Excel文件
  • 原文地址:https://www.cnblogs.com/curo0119/p/8413863.html
Copyright © 2011-2022 走看看