目录
一、全排列
输入一个数n,输出这个数的全排列。
public class Test { static int[] v=new int[20]; static int n; static List<List<Integer>> reslist=new ArrayList<>(); public static void main(String[] args) { Scanner scanner=new Scanner(System.in); n=scanner.nextInt(); List<Integer> list=new ArrayList<>(); dfs(list); for(List<Integer> l:reslist){ for(Integer x:l){ System.out.print(x+" "); } System.out.println(); } } public static void dfs(List<Integer> list){ if(list.size()==n){ reslist.add(new ArrayList(list)); } for(int i=1;i<=n;i++){ if(v[i]==0){ v[i]=1; list.add(i); dfs(list); v[i]=0; list.remove(list.size()-1); } } } }
二、0开心
题目链接:0开心
import java.util.*; public class Main { static long max=Long.MIN_VALUE,min=Long.MAX_VALUE; public static void main(String[] args) { Scanner scanner=new Scanner(System.in); char[] c= scanner.next().toCharArray(); int k=scanner.nextInt(); StringBuilder stringBuilder=new StringBuilder(); dfs(0,k,c,stringBuilder); System.out.println(max-min); } public static void dfs(int u,int k,char[] c,StringBuilder stringBuilder){ if(u==c.length){ if(k==0){ String[] s=stringBuilder.toString().split("\\+"); long sum=0; for(String x:s){ sum+=Long.valueOf(x); } max=Math.max(max,sum); min=Math.min(min,sum); } return; } stringBuilder.append(c[u]); dfs(u+1,k,c,stringBuilder); stringBuilder.deleteCharAt(stringBuilder.length()-1); if(k>0&&u<c.length-1){ //u<c.length-1是因为最后一个不需要再加加号了 stringBuilder.append(c[u]); stringBuilder.append("+"); dfs(u+1,k-1,c,stringBuilder); stringBuilder.deleteCharAt(stringBuilder.length()-1); stringBuilder.deleteCharAt(stringBuilder.length()-1); } } }
三、特殊的三角形
题目链接:特殊的三角形
本题其实没有使用dfs算法,但是采用了剪枝的概念,避免了重复计算。
假设a<b<c,v<10^6(注意题目在说规模的时候,说的是所有的评测数据)推出a<100,b<1000,c<a+b
public static void main(String[] args) { Scanner scanner=new Scanner(System.in); long[] sum=new long[(int)1e6+1]; for(int a=1;a<100;a++){ for(int b=a+1;b<1000;b++){ for(int c=b+1;c<a+b;c++){ if(check(a,b,c)&&((a*b*c)<sum.length)){ sum[a*b*c]++; } } } } //计算前缀和 for(int i=1;i<sum.length;i++){ sum[i]+=sum[i-1]; } int t=scanner.nextInt(); while(t-->0){ int l=scanner.nextInt(); int r=scanner.nextInt(); System.out.println(sum[r]-sum[l-1]); } } public static boolean check(int a,int b,int c){ //判断是不是三角形 if(((a+b)>c)&&((a+c)>b)&&((b+c)>a)){ return true; } return false; }
四、小怂爱水洼
题目链接:小怂爱水洼
import java.util.*; public class Main { static int n,m; static int[][] a=new int[110][110]; static int[][] v=new int[110][110]; static long ans=0,sum=0;//作为每个水洼的最大值 static int[] dx={1,-1,0,0}; static int[] dy={0,0,1,-1}; public static void main(String[] args){ Scanner scanner=new Scanner(System.in); n=scanner.nextInt(); m=scanner.nextInt(); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ a[i][j]=scanner.nextInt(); } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ sum=0; dfs(i,j); ans=Math.max(sum,ans); } } System.out.print(ans); } public static void dfs(int x,int y){ if(x<1||x>n||y<1||y>m){ return; } if(a[x][y]==0||v[x][y]==1){ return; } sum+=a[x][y]; v[x][y]=1; for(int i=0;i<4;i++){ int xx=dx[i]+x; int yy=dy[i]+y; if(a[xx][yy]!=0&&v[xx][yy]==0){ dfs(xx,yy); } } } }
五、混境之地5
题目链接:混境之地5
本题采用了记忆化搜索的思想,dp表示该点的位置是否搜索过,最后在判断终点的dp值即可判断是否可以出去.
import java.util.*; public class Main { static int n,m,k; static int a,b,c,d; static int[][] f; static int[][] dp;//dp=1表示改地点已经访问 static int[] dx={1,-1,0,0}; static int[] dy={0,0,1,-1}; public static void main(String[] args) { Scanner scanner=new Scanner(System.in); n=scanner.nextInt(); m=scanner.nextInt(); k=scanner.nextInt(); a=scanner.nextInt()-1;//坐标起点有0 b=scanner.nextInt()-1; c=scanner.nextInt()-1; d=scanner.nextInt()-1; f=new int[n][m]; dp=new int[n][m]; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ f[i][j]=scanner.nextInt(); } } //第三个参数表示是否已经使用了喷气背包,为0表示还未使用 dfs(a,b,0); if(dp[c][d]==1){ System.out.println("Yes"); } else{ System.out.println("No"); } } public static void dfs(int x,int y,int flag){ dp[x][y]=1; for(int i=0;i<4;i++){ int xx=dx[i]+x; int yy=dy[i]+y; if(xx<0||xx>=n||yy<0||yy>=m||dp[xx][yy]==1)continue; if(f[xx][yy]<f[x][y]){ dfs(xx,yy,flag); } else{ if(((f[xx][yy])<(f[x][y]+k))&&(flag==0)){ //使用了喷气背包 dfs(xx,yy,1); } } } } }