蓝桥杯--递归2

AcWing 93. 递归实现组合型枚举

原题链接

输入n,m,且m<n,输出1~n的m位升序全排列。

自己的思路是传两参dfs,分别是数值s和数位t,根据特性从1~m来分别dfs,dfs中首先翻s的牌子,再从s+1开始继续遍历dfs,直至数位t==m时输出。不过一直觉得dfs传两参还要加个for循环确实是太捞了

package atta;

import java.io.*;
import java.util.*;


public class Main {
    
    
	static Scanner tab = new Scanner(System.in);
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
	static int N = 100010;
	
	static int bg[][]=new int [20][20];
	static int g[][]=new int [20][20];
	
	static int n,m;
	static boolean st[]=new boolean[N];
	
	static void dfs(int s,int t) {
    
    
		st[s]=true;
		if(t==m) {
    
    
			for(int i=1;i<=n;i++) {
    
    
				if(st[i]) {
    
    
					System.out.print(i+" ");
				}
			}
			System.out.println();
			return ;
		}
		for(int i=s+1;i<=n;i++) {
    
    
			dfs(i,t+1);
			st[i]=false;
		}
		st[s]=false;
	}
	
	
	public static void main(String[] args) throws IOException {
    
    
		n=tab.nextInt();
		m=tab.nextInt();
		for(int i=1;i<=m;i++) {
    
    
			dfs(i,1);			
		}
		
	}
}


不过这题和指数型枚举还是差不多的,只需要加上限制条件,一样可以使用动态数组的方法来实现

package atta;

import java.io.*;
import java.util.*;

public class Main {
    
    
	static Scanner tab = new Scanner(System.in);
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
	static int N = 100010;

	static int n, m;
	static Vector<Integer> v = new Vector<Integer>();

	static void dfs(int t) {
    
    
		//容器内数量大于m或当前数量加上剩余的最大数量仍不足m的两种情况下直接返回
		if (v.size() > m || v.size() + (n - t + 1) < m) {
    
    
			return;
		}
		if (t > n) {
    
    
			for (int i = 0; i < v.size(); i++) {
    
    
				System.out.print(v.get(i) + " ");
			}
			System.out.println();
			return;
		}
		v.add(t);
		dfs(t + 1);
		v.remove(v.size() - 1);
		dfs(t + 1);
	}

	public static void main(String[] args) throws IOException {
    
    
		n = tab.nextInt();
		m = tab.nextInt();
		dfs(1);

	}
}


AcWing 1209. 带分数

原题链接

将1~9分成a*(b/c)的形式,判断有多少种组合方式使之等于n

还是只会笨比做法,dfs求出1~9的全排列,再用双指针将全排列分成三部分也就是abc三个值,计算即可,要注意计算时会爆int,可以将分母移到另一边或直接用long
其实应该是可以剪枝优化的,学会了再填坑==


import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Scanner;

public class Main {
    
    
	static Scanner tab = new Scanner(System.in);
	static BufferedWriter tabb = new BufferedWriter(new OutputStreamWriter(System.out));
	static int N = 10;
	
	static int num[]=new int [N];
	static int vis[]=new int [N];
	static int cnt=0;
	static int t ;
	
	static int cal(int l,int r) {
    
    
		int sum=0;
		for(int i=l;i<=r;i++) {
    
    
			sum=sum*10+num[i];
		}
		return sum;
	}
	
	static void dfs(int u) {
    
    
		if(u>9) {
    
    
			for(int i=1;i<=7;i++) {
    
    
				for(int j=i+1;j<=8;j++) {
    
    
					int a=cal(1,i);
					int b=cal(i+1,j);
					int c=cal(j+1,9);
					if(a*c+b==c*t)
						cnt++;
				}
			}
		}
		
		for(int i=1;i<=9;i++) {
    
    
			if(vis[i]==0) {
    
    
				num[u]=i;
				vis[i]=1;
				dfs(u+1);
				vis[i]=0;
			}
		}
	}
	
	public static void main(String[] args) throws IOException {
    
    
		t=tab.nextInt();
		dfs(1);
		System.out.println(cnt);
	}
}

保持好心态的要诀是远离堡垒,多吃垃圾:)

猜你喜欢

转载自blog.csdn.net/ooold_six/article/details/114851504