递归
92. 递归实现指数型枚举 - AcWing题库
import java.util.*;
public class Main{
static int N = 16, n;
static int[] st = new int[N];//st[x] 等于0表示还没考虑到它,等于1表示选它,等于2表示不选它
public static void dfs(int u){
if(u > n){
for(int i = 1; i <= n; i ++){
if(st[i] == 1) System.out.print(i + " ");
}
System.out.println();
return;//一定要记得返回return
}
//不选的情况
st[u] = 2;
dfs(u + 1);
st[u] = 0;//恢复现场
//选的情况
st[u] = 1;
dfs(u + 1);
st[u] = 0;//恢复现场
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
dfs(1);//由于数字范围是1到n,所以这里的dfs要从1开始,不从0开始
}
}
94. 递归实现排列型枚举 - AcWing题库
import java.util.*;
public class Main{
static int N = 10, n;
static int[] path = new int[N];//记录每一层的数
static boolean[] st = new boolean[N];//用来判断这个数是否用过
public static void dfs(int u){
if(u > n){
for(int i = 1; i <= n; i ++){
System.out.print(path[i] + " ");
}
System.out.println();
}
for(int i = 1; i <= n; i ++){
if(!st[i]){
path[u] = i;
st[i] = true;
//递归下一层
dfs(u + 1);
//恢复现场
path[u] = 0;
st[i] = false;
}
}
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
dfs(1);
}
}
93. 递归实现组合型枚举 - AcWing题库
限制:从小到大排序(局部限制),保证每次加的数都比前一个数大
import java.util.*;
public class Main{
static int N = 30, n, m;
static int[] state = new int[N];
public static void dfs(int u, int start){
if(u - 1 + n - start + 1 < m) return;//剪枝
if(u == m + 1){
for(int i = 1; i <= m; i ++){
System.out.print(state[i] + " ");
}
System.out.println();
}
for(int i = start; i <= n; i ++){
state[u] = i;
dfs(u + 1, i + 1);
state[u] = 0;//恢复现场
}
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
dfs(1, 1);//从第一个位置开始,当前可以从1开始选
}
}
1209. 带分数 - AcWing题库
import java.util.*;
import java.io.*;
public class Main{
static int N = 20;
static int n, res;
static boolean[] st = new boolean[N], cpy = new boolean[N];
public static void dfs_a(int u, int a){
if(a >= n) return;//大于n直接返回
if(a > 0) dfs_c(u, a, 0);//枚举c的所有排列方案
for(int i = 1; i <= 9; i ++){
if(!st[i]){
st[i] = true;
dfs_a(u + 1, a * 10 + i);
st[i] = false;//恢复现场
}
}
}
public static void dfs_c(int u, int a, int c){
if(u > 9) return;
if(check(a, c)) res ++;
for(int i = 1; i <= 9; i ++){
if(!st[i]){
st[i] = true;
dfs_c(u + 1, a, c * 10 + i);
st[i] = false;//恢复现场
}
}
}
public static boolean check(int a, int c){
long b = (long) (n - a) * c;
cpy = Arrays.copyOf(st, N);
while(b > 0){
int t = (int)(b % 10);
b = b / 10;
if(t == 0 || cpy[t]) return false;//如果t为0,或者被用过
cpy[t] = true;
}
//检查是否有遗漏
for(int i = 1; i <= 9; i ++){
if(!cpy[i]) return false;
}
return true;
}
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
dfs_a(0, 0);//一开始a和c共用0个数,a为0
System.out.print(res);
}
}
递推
717. 简单斐波那契 - AcWing题库
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int[] f = new int[46];
f[1] = 0;
f[2] = 1;
int n = sc.nextInt();
for(int i = 3; i <= n; i ++){
f[i] = f[i - 1] + f[i - 2];
}
for(int i = 1; i <= n; i ++){
System.out.print(f[i] + " ");
}
}
}
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int a = 0, b = 1;
for(int i = 1; i <= n; i ++){
System.out.print(a + " ");
int c = a + b;
a = b;
b = c;
}
}
}
95. 费解的开关 - AcWing题库
1.顺序可以任意
2.每个格子最多按一次
每一行开关的操作都被前一行的开关状态所决定
import java.util.*;
public class Main{
static int N = 6;
static int[][] g = new int[N][N];
static int[][] backup = new int[N][N];
static int[] dx = {-1, 0, 1, 0, 0}, dy = {0, 1, 0, -1, 0};
public static void turn(int x, int y){
for(int i = 0; i < 5; i ++){
int a = x + dx[i];
int b = y + dy[i];
if(a < 0 || b < 0 || a >= 5 || b >= 5) continue;
g[a][b] ^= 1;
}
}
public static int dfs(){
int ans = 0x3f3f3f3f;
//备份数组,用于多组测试(32)
for(int i = 0; i < 5; i ++){
for(int j = 0; j < 5; j ++){
backup[i][j] = g[i][j];
}
}
for(int k = 0; k < 1 << 5; k ++){
int res = 0;//本次循环的结果
//第一行
for(int j = 0; j < 5; j ++){
if((k >> j & 1) == 0){
res ++;
turn(0, j);
}
}
for(int i = 0; i < 4; i ++){//第一行到第四行
for(int j = 0; j < 5; j ++){//第一个数到第五个数
if(g[i][j] == 0){
res ++;
turn(i + 1, j);
}
}
}
boolean flag = true;
for(int j = 0; j < 5; j ++){//判断最后一行是否全为1
if(g[4][j] == 0){
flag = false;
break;
}
}
if(flag) ans = Math.min(ans, res);
for(int i = 0; i < 5; i ++){
for(int j = 0; j < 5; j ++){
g[i][j] = backup[i][j];//复原数组,便于下次循环
}
}
}
if(ans > 6) return -1;
else return ans;
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
while(T -- > 0){
for(int i = 0; i < 5; i ++){
String s = sc.next();
for(int j = 0; j < 5; j ++){
g[i][j] = s.charAt(j) - '0';//转化为int类型
}
}
System.out.println(dfs());
}
}
}
1208. 翻硬币 - AcWing题库
次数和顺序没有关系
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String a = sc.next();
String b = sc.next();
int res = 0;
char[] A = a.toCharArray();
char[] B = b.toCharArray();
for(int i = 0; i < a.length(); i ++){
if(A[i] != B[i]){
res ++;
if(B[i + 1] == '*') B[i + 1] = 'o';
else B[i + 1] = '*';
}
}
System.out.print(res);
}
}
116. 飞行员兄弟 - AcWing题库
暴力枚举所有方案(0 ~ 2^16 - 1),按照该方案对所有开关进行操作,然后判断,记录方案
import java.util.*;
class PII{
int x, y;
public PII(int x, int y){
this.x = x;
this.y = y;
}
}
public class Main{
static int N = 5;
static char[][] g = new char[N][N];
static char[][] backup = new char[N][N];
//找到每个位置的编号
public static int get(int x, int y){
return 4 * x + y;
}
//改变同一行同一列元素的状态
public static void turn_all(int x, int y){
for(int i = 0; i < 4; i ++){
turn_one(x, i);
turn_one(i, y);
}
turn_one(x, y);
}
//具体的改变函数
public static void turn_one(int x, int y){
if(g[x][y] == '+') g[x][y] = '-';
else g[x][y] = '+';
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
//输入数据
for(int i = 0; i < 4; i ++){
String s = sc.next();
for(int j = 0; j < 4; j ++){
g[i][j] = s.charAt(j);
}
}
List<PII> res = new ArrayList<>();//用来记录最终路径
for(int k = 0; k < 1 << 16; k ++){
List<PII> temp = new ArrayList<>();
//备份
for(int i = 0; i < 4; i ++){
backup[i] = g[i].clone();
}
for(int i = 0; i < 4; i ++){
for(int j = 0; j < 4; j ++){
if((k >> get(i, j) & 1) == 1){
temp.add(new PII(i, j));//记录路径
turn_all(i, j);//改变同一行同一列元素的状态
}
}
}
boolean flag = true;//检查开关是否都打开了
for(int i = 0; i < 4; i ++){
for(int j = 0; j < 4; j ++){
if(g[i][j] == '+'){
flag = false;
}
}
}
if(flag){
if(res.size() == 0 || res.size() > temp.size()) res = temp;//如果还没有合法值,或者当前值比合法值小
}
//复原
for(int i = 0; i < 4; i ++){
g[i] = backup[i].clone();
}
}
System.out.println(res.size());
for(PII i: res){
System.out.println((i.x + 1) + " " + (i.y + 1));
}
}
}