奇妙的算法【8】筹钱种数、定时找出最高频次的数据、三子棋落点判断

1,筹钱种数

  有几种不同币值的钱币,求有多少种可能情况凑成m元钱

  咔咔,直接递归调用超级简单。

package com.cnblogs.mufasa.Main1;

import java.util.Arrays;
import java.util.Scanner;

public class Solution {

    public static int RecuDeal(int[] nums,int sum,int index){
        int cont=0;
        if(index==nums.length-1){//1,退出条件:只有最后一个数据选项
            if(sum%nums[index]==0){//1,1可以匹配上,余数为0
                cont= 1;
            }else {//1,2 无法匹配上,余数不为零
                cont= 0;
            }
        }else {//2,还有多个数据可以选择,进一步进行拆分递进递归
            int temp=sum/nums[index];
            for(int i=0;i<=temp;i++){
                cont+=RecuDeal(nums,sum-nums[index]*i,index+1);//递归节点
            }
        }
        return cont;
    }

    public static void main(String[] args) {

        //1,测试
        int[] nums=new int[]{5,2,1};
        int sum=10;

        //2,输入
//        Scanner sc=new Scanner(System.in);
//        String[] strs=sc.nextLine().split(" ");
//        int sum=sc.nextInt();
//        int[] nums=new int[strs.length];
//        for(int i=0;i<strs.length;i++){
//            nums[i]=Integer.valueOf(strs[i]);
//        }

        //3,输出
        System.out.println(RecuDeal(nums,sum,0));//输出结果为10正确
    }
}
/*
5 2 1
10

 */

2,计算机日志报告使用频次

  输出每五分钟内使用频次最大的数据频次及其名称

  咔咔,①使用Node节点类型将这个对象进行实例化,方便计算时间,存储名称;②使用hashMap来进行频次的统计,key为我们定义的数据

package com.cnblogs.mufasa.Main2;

import java.util.*;

class myDate{
    int year;
    int month;
    int day;
    int hour;
    int min;
    int sec;
    public myDate(String str){
        this.year=Integer.valueOf(str.substring(0,4));
        this.month=Integer.valueOf(str.substring(5,7));
        this.day=Integer.valueOf(str.substring(8,10));
        this.hour=Integer.valueOf(str.substring(11,13));
        this.min=Integer.valueOf(str.substring(14,16));
        this.sec=Integer.valueOf(str.substring(17,19));
    }

    //用于判断是否超过5分钟
    public boolean subDate(myDate o){
        if(o.year>year){
            return true;
        }
        if(o.month>month){
            return true;
        }
        if(o.day>day){
            return true;
        }
        if(o.hour>hour){
            return true;
        }
        if(o.min-min>5){
            return true;
        }else if(o.min-min==5){//分钟时刻刚好相差5min,需要使用秒时快进一步比较
            if(o.sec>sec){//秒时刻多输出true
                return true;
            }
        }
        return false;//其他所有情况,都输出false:没有超过5min
    }
}

public class Solution {
    private static HashMap<String,Integer> hm=new HashMap();//统计频次
    private static myDate staTime=null;//基准时刻

    public static void SinInput(String str){
        String time=str.substring(0,19);
        String intName=str.substring(20);

        myDate preDate=new myDate(time);

        if(staTime==null){
            staTime=preDate;
            hm.put(intName,1);//将这个数据添加进hm
            return;
        }

        if(!staTime.subDate(preDate)){//1,没有超过5分钟,直接在hashMap中添加或者累积
            if(hm.containsKey(intName)){//1,1hm中有原始的数据
                hm.put(intName,hm.get(intName)+1);
            }else {//1,2hm中没有原始的数据
                hm.put(intName,1);
            }

        }else {//2,超过5分钟,将本轮数据的 最大频数及名称输出
            int num=0;
            String name="";
            for(String key:hm.keySet()){
                if(num<hm.get(key)){
                    name=key;
                    num=hm.get(key);
                }
            }
            System.out.println(num+" "+name);
            hm.clear();
            hm.put(intName,1);
        }
    }

    public static void FinWork(){//主动退出,并且处理,清空hm中剩余数据
        int num=0;
        String name="";
        for(String key:hm.keySet()){
            if(num<hm.get(key)){
                name=key;
                num=hm.get(key);
            }
        }
        System.out.println(num+" "+name);
        hm.clear();
    }

    public static void main(String[] args) {
        //1,测试
        ArrayList<String> arr=new ArrayList<>();
        arr.add("2019-09-10T10:00:01 /api/a");
        arr.add("2019-09-10T10:00:01 /api/a");
        arr.add("2019-09-10T10:00:01 /api/b");
        arr.add("2019-09-10T10:06:00 /api/a");

        //2,输入
        Scanner sc=new Scanner(System.in);

        //3,输入&处理
        for(int i=0;i<arr.size();i++){
            SinInput(arr.get(i));
        }
        FinWork();//主动退出,并处理剩余数据

    }
}
/*
2 /api/a
1 /api/a
 */

3,找出三子棋最有利的落点

  有一种3x3大小的正方形棋盘,类似五子棋玩法横竖斜着三种颜色相连就胜利,求出下一个棋子的最佳落点,默认黑子先手

  咔咔,这个是一个二维的问题!直接在水平、竖直、斜向进行检测,并且将检测结构存于hashMap中,其实这里可以进一步推广,变成动态的自动下棋软件。

package com.cnblogs.mufasa.Main3;

import java.util.ArrayList;
import java.util.HashMap;

public class Solution {
    private static HashMap<Integer, ArrayList<int[]>> hm=new HashMap<>();

    public static void findX(int[][] map,int type){//直接横向的进行遍历
        int lenX=map.length;
        int lenY=map[0].length;

        ArrayList<int[]> arr=new ArrayList<>();
        int sum;
        for(int i=0;i<lenX;i++){
            sum=lenY;
            for(int j=0;j<lenY;j++){
                if(map[i][j]==-1*type){//1,1是另外颜色的落子,本行无法取胜,直接清空数据跳出
                    arr.clear();
                    break;
                }else if(map[i][j]==type){//1,2是该颜色的落子,胜率加大
                    sum--;
                }else {//1,3是空位点,可以落子
                    arr.add(new int[]{i,j});
                }
            }

            if(arr.size()!=0){//1,4有可能的位点
                if(hm.containsKey(sum)){//1,4,1原始hm中有相关sum数据
                    arr.addAll((ArrayList<int[]>)hm.get(sum).clone());
                    hm.put(sum,(ArrayList<int[]>)arr.clone());
                    arr.clear();
                }else {//1,4,2原始hm中没有相关sum数据
                    hm.put(sum,(ArrayList<int[]>) arr.clone());
                    arr.clear();
                }
            }

        }
    }

    public static void findY(int[][] map,int type){//直接纵向的进行遍历
        int lenX=map.length;
        int lenY=map[0].length;
        ArrayList<int[]> arr=new ArrayList<>();
        int sum;
        for(int i=0;i<lenX;i++){
            sum=lenY;
            for(int j=0;j<lenY;j++){
                if(map[j][i]==-1*type){//1,1是另外颜色的落子,本行无法取胜
                    arr.clear();
                    break;
                }else if(map[j][i]==type){//1,2是该颜色的落子,胜率加大
                    sum--;
                }else {//1,3是空位点,可以落子
                    arr.add(new int[]{j,i});
                }
            }

            if(arr.size()!=0){//1,4有可能的位点
                if(hm.containsKey(sum)){//1,4,1原始hm中有相关sum数据
                    arr.addAll((ArrayList<int[]>)hm.get(sum).clone());
                    hm.put(sum,(ArrayList<int[]>)arr.clone());
                    arr.clear();
                }else {//1,4,2原始hm中没有相关sum数据
                    hm.put(sum,(ArrayList<int[]>) arr.clone());
                    arr.clear();
                }
            }

        }
    }

    public static void findZ(int[][] map,int type){//进行斜向的遍历
        int lenX=map.length;
        int lenY=map[0].length;
        int len=Math.min(lenX,lenY);

        ArrayList<int[]> arr=new ArrayList<>();
        int sum=len;

        for(int i=0;i<len;i++){//左上至右下
            if(map[i][i]==-1*type){
                arr.clear();
                break;
            }else if(map[i][i]==type){
                sum--;
                if(sum==0){
                    break;
                }
            }else {
                arr.add(new int[]{i,i});
            }
        }

        if(arr.size()!=0){
            if(hm.containsKey(sum)){
                arr.addAll((ArrayList<int[]>)hm.get(sum).clone());
                hm.put(sum,(ArrayList<int[]>)arr.clone());
                arr.clear();
            }else {
                hm.put(sum,(ArrayList<int[]>) arr.clone());
            }
            arr.clear();
        }

        sum=len;
        for(int i=0;i<len;i++){//右上至左下
            if(map[i][len-1-i]==-1*type){
                arr.clear();
                break;
            }else if(map[i][len-1-i]==type){
                sum--;
                if(sum==0){
                    break;
                }
            }else {
                arr.add(new int[]{i,len-i-1});
            }
        }

        if(arr.size()!=0){
            if(hm.containsKey(sum)){
                arr.addAll((ArrayList<int[]>)hm.get(sum).clone());
                hm.put(sum,(ArrayList<int[]>)arr.clone());
                arr.clear();
            }else {
                hm.put(sum,(ArrayList<int[]>) arr.clone());
            }
            arr.clear();
        }
    }

    public static void toOut(int type){//数据输出
        for(int i=0;i<=3;i++){
            if(hm.containsKey(i)){
                if(type==-1){
                    System.out.print("B:");
                }else {
                    System.out.print("W:");
                }
                for(int[] temp:hm.get(i)){
                    System.out.print("("+temp[0]+","+temp[1]+")");
                }
                System.out.println();
                hm.clear();
                break;
            }
        }
    }

    public static void main(String[] args) {

        //1,测试
        int[][] map=new int[][]{{0, 1, 0},
                                {0,-1, 0},
                                {0, 0, 0}};//-1表示黑子,1表示白子,0表示空位

        //2,输入
//        Scanner sc=new Scanner(System.in);

        //3,处理输出
        int bNum=0;
        int wNum=0;
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                if(map[i][j]==-1){
                    bNum++;
                }else if(map[i][j]==1){
                    wNum++;
                }
            }
        }

        int type=(bNum==wNum?-1:1);
        findX(map,type);
        findY(map,type);
        findZ(map,type);
        toOut(type);

    }
}
原文地址:https://www.cnblogs.com/Mufasa/p/11534223.html