奇妙的算法-回文树最优化卷积判断

Posted mufasa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了奇妙的算法-回文树最优化卷积判断相关的知识,希望对你有一定的参考价值。

 

1,判断一个十进制正整数的二进制数是否为回文

技术图片
package com.cnblogs.mufasa.answer1;

import java.util.Scanner;

public class Main 
    public static void main(String[] args) 
        //0,测试专用数据
//        int[] nums=1,4,7;

        //1,数据输入
        Scanner sc=new Scanner(System.in);
        int T=sc.nextInt();
        int[] nums=new int[T];
        for(int i=0;i<T;i++)
            nums[i]=sc.nextInt();
        

        //2,输入数据验证
//        printOut(nums);//验证正确

        //3,正常处理数据
        for(int temp:nums)
            Judge(temp);
        
    

    //3,单个数据监测是否二进制是回文
    public static void Judge(int temp)
        String str="";
        //3.1,数值转换
        while (temp!=0)
            str=temp%2+str;
            temp=temp/2;
        
        //3.2,数据判断
        String out="YES";
        int len=str.length();
        for(int i=0;i<len/2;i++)
            if(str.charAt(i)!=str.charAt(len-1-i))
                out="NO";
                break;//提前跳出
            
        
        //3.3,结论输出
        System.out.println(out);
    

    //2,测试输入是否正确
    public static void printOut(int[] nums)
        for(int temp:nums)
            System.out.println(temp);
        
    


/*
输入样例:
3
1
4
7
输出样例:
YES
NO
YES
 */
View Code

 

2,构建二叉树,找出根节点,然后层次遍历判断

技术图片
package com.cnblogs.mufasa.answer2;

import java.util.Scanner;
import java.util.*;


class Node//节点辅助类
    int value;
    int left;
    int right;
    public Node(int value, int left, int right) 
        this.value = value;
        this.left = left;
        this.right = right;
    


public class Main 
    public static void main(String[] args)

        //1,数据输入
        Scanner in = new Scanner(System.in);
        while (in.hasNext())
            String line1=in.nextLine();
            int T=Integer.valueOf(line1);

            List<Boolean> ret=new ArrayList<>();
            for (int i=0;i<T;i++)
                String line=in.nextLine();
                int N=Integer.valueOf(line);
                Node[] nodes = new Node[N];

                for (int j=0;j<N;j++)
                    String[] nodeData=in.nextLine().split(" ");
                    nodes[j]=new Node(Integer.valueOf(nodeData[0]),
                            Integer.valueOf(nodeData[1]),
                            Integer.valueOf(nodeData[2]));
                
                //2,数据处理
                ret.add(judge(nodes));
            
            //3,数据输出
            for (Boolean bool:ret)
                String s;
                if (bool)
                    s="YES";
                else
                    s="NO";
                
                System.out.println(s);
            
        
    

    //2,数据处理
    private static boolean judge(Node[] nodes)
        int root=findRoot(nodes);
        Stack<Integer> stack=new Stack<>();
        int last=nodes[root].value;
        stack.push(root);
        while (!stack.isEmpty())
            int sum=0;
            List<Integer> list=new ArrayList<>();
            while (!stack.isEmpty())
                int index=stack.pop();
                int left=nodes[index].left;
                int right=nodes[index].right;

                if (left!=-1)
                    sum+=nodes[left].value;
                    list.add(left);
                

                if (right!=-1)
                    sum+=nodes[right].value;
                    list.add(right);
                
            

            if (last>=sum&&list.size()>0)
                return false;
            

            last=sum;
            for (int index:list)
                stack.push(index);
            
        
        return true;
    

    //寻找根节点
    private static int findRoot(Node[] nodes)
        int[] array=new int[nodes.length];
        for (Node node:nodes)
            if (node.left!=-1)
                array[node.left]=1;
            
            if (node.right!=-1)
                array[node.right]=1;
            
        

        for (int i=0;i<array.length;i++)
            if (array[i]<1)
                return i;
            
        
        return -1;
    




/*
输入样例:
2
8
2 -1 -1
1 5 3
4 -1 6
2 -1 -1
3 0 2
2 4 7
7 -1 -1
2 -1 -1
8
21 6 -1
52 4 -1
80 0 3
31 7 -1
21 -1 -1
59 -1 -1
50 5 -1
48 -1 1

输出样例:
YES
NO
 */
View Code

 

3,如何在30个单位中插入最多的元素

技术图片
package com.cnblogs.mufasa.answer3;

import java.util.ArrayList;
import java.util.Scanner;

public class Main 
    public static void main(String[] args) 

        //1,数据输入
        Scanner sc=new Scanner(System.in);
        int T=sc.nextInt();
        int[][] KM=new int[T][2];
        ArrayList<ArrayList<Integer>> arr=new ArrayList<>(T);
        for(int i=0;i<T;i++)
            KM[i][0]=sc.nextInt();
            KM[i][1]=sc.nextInt();
            ArrayList<Integer> preArr=new ArrayList<Integer>(KM[i][1]);
            arr.add(preArr);
            for(int j=0;j<KM[i][1];j++)
                preArr.add(sc.nextInt());
            
        

        //2,输入数据验证
//        printOut(arr);

        //3,数据处理
        for(int i=0;i<T;i++)
            ArrayList<Integer> preArr=arr.get(i);
            dealSum(KM[i][0],KM[i][1],preArr);
        

    

    //3.1,数据处理  全局处理
    public static void dealSum(int k,int m,ArrayList<Integer> preArr)
        int ans=0;
        if(m==0)//3.1,没有固定的天数【正确】
            ans=dealSingle(k,1,30);
        else if(preArr.get(0)==1)//3.2,有固定天数,第一天为1【正确】
            ans=m;
            for(int i=1;i<preArr.size();i++)
                ans=ans+dealSingle(k,preArr.get(i-1)+k+1,preArr.get(i)-k-1);
            
            ans=ans+dealSingle(k,preArr.get(m-1)+k+1,30);
        else //3.3,有固定的天数,第一天不为1【正确】
            ans=m;
            ans=ans+dealSingle(k,1,preArr.get(0)-k-1);
            for(int i=1;i<preArr.size();i++)
                ans=ans+dealSingle(k,preArr.get(i-1)+k+1,preArr.get(i)-k-1);
            
            ans=ans+dealSingle(k,preArr.get(m-1)+k+1,30);
        
        System.out.println(ans);
    

    //3.2,数据处理  单个区间处理
    public static int dealSingle(int k,int index0,int index1)//index0可以,index1可以
        if(index1<index0)//非法输入无法进行日期选定
            return 0;
        else if(index1-index0<k&&index1>=index0)//不够展开,只能在其中任选一天
            return 1;
        
        int cont=1;//可以展开,可以进行最大化日期选择
        int index=index0;
        while (index<=index1-k-1)
            cont++;
            index+=k+1;
        
//        System.out.println("cont:"+cont);
        return cont;
    

    //2,输入数据验证【验证正确】
    public static void printOut(ArrayList<ArrayList<Integer>> arr)
        for(int i=0;i<arr.size();i++)
            ArrayList<Integer> preArr=arr.get(i);
            for(int j=0;j<preArr.size();j++)
                System.out.print(preArr.get(j)+"-");
            
            System.out.println();
        
    

/**
 * 1,只有间隔
 */


/*
1
1 0

1
5 0

输入样例:
4
0 10
1 2 3 4 5 6 7 8 9 10
1 15
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29
1 7
5 9 13 17 21 25 29
1 0


输出样例:
30
15
15
15

 */
View Code

 

4,获取最大的合法框图的坐标点【reture无法跳出循环】

技术图片
package com.cnblogs.mufasa.myWorkStation;

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

public class Main4 
    private static boolean[] flags=new boolean[9];//true表示1,false表示0
    static 
        flags[0]=true;
        flags[2]=true;
        flags[6]=true;
        flags[8]=true;
        for(int i=0;i<9;i++)
            flags[i]=!flags[i];
        
    

    public static void main(String[] args) 
        ArrayList<int[][]> cacheArr=new ArrayList<>();
        Scanner in=new Scanner(System.in);
        while (in.hasNext()) 
            String line1 = in.nextLine();
            int t = Integer.valueOf(line1);
            for (int i = 0; i < t; i++) 
                String[] nm = in.nextLine().split(" ");
                int n = Integer.valueOf(nm[0]);
                int m = Integer.valueOf(nm[1]);
                int[][] arr = new int[n][m];
                for (int j = 0; j < n; j++) 
                    String newLine = in.nextLine();
                    for (int k = 0; k < m; k++) 
                        arr[j][k] = newLine.charAt(k) - 0;
                    
                
                cacheArr.add(arr);
                //3,数据验证
//                for (int[] a : arr) 
//                    System.out.println(Arrays.toString(a));
//                
            //一组数据输入完成

            for(int i=0;i<cacheArr.size();i++)
                int[][] arr=cacheArr.get(i);
                int n=arr.length,m=arr[0].length;
                //2,数据处理
                dealSum(cacheArr.get(i),n,m);
            
        


    

    //2.1,数据处理函数 sum    全局搜索:由大到小的搜索是否存在
    public static void dealSum(int[][] arr,int N,int M)
        int MIN=(N<M?N:M);
        String strPre="-1 -1 -1 -1";
        String strOut;
        while (MIN>=3)
            if (MIN%3==0)//刚好可以成为一个9宫格
                strOut=dealSingle(arr,N,M, MIN);
                if(strOut!=strPre)
                    strPre=strOut;
                    break;
                
            
            MIN--;
        
        System.out.println(strPre);
    

    //2.2,数据处理 single   固定9宫格的大小,在arr中搜索是否存在
    public static String dealSingle(int[][] arr,int N,int M,int MIN)
        int minLen=MIN/3;
        String outStr="-1 -1 -1 -1";
        loop:for(int i=0;i<N-MIN+1;i++)
            for(int j=0;j<M-MIN+1;j++)
                boolean sinFlag=dealMin(arr, MIN, minLen, i, j);
//                System.out.println((i+1)+" "+(j+1)+" "+ (i+MIN)+" "+(j+MIN)+":"+sinFlag);
                if(sinFlag==true)
//                    System.out.println("数据处理----------");
                    outStr=((i+1)+" "+(j+1)+" "+ (i+MIN)+" "+(j+MIN));
//                    System.out.println(outStr);
//                    System.out.println("数据处理----------");
                    return outStr;
//                    break loop;
                
            
        
        return outStr;
    

    //2.3,数据处理 min  固定9宫格,固定index位置,判断是否可以
    public static boolean dealMin(int[][] arr,int MIN,int minLen,int index0,int index1)
        for(int num=0;num<9;num++)
            boolean minFlag=dealSqure(arr,minLen,index0+num/3*minLen,index1+num%3*minLen,flags[num]);
            if(!minFlag)
                return false;
            
        
        return true;
    

    //2.4,数据处理  squre 方块中是否全为1或者0
    public static boolean dealSqure(int[][] arr,int minLen,int index0,int index1,boolean type)
        int mark=(type?1:0);
        for(int i=index0;i<index0+minLen;i++) 
            for (int j = index1; j < index1+minLen; j++) 
                if(arr[i][j]!=mark)
                    return false;
                
            
        
        return true;
    


/*
输入样例:
3
3 3
111
000
111
6 6
010010
111111
010010
010010
111111
010010
8 8
01000001
11100001
01001100
11001100
00111111
00111111
00001100
11001100

输出样例:
-1 -1 -1 -1
1 1 3 3
3 3 8 8
 */
View Code

 

以上是关于奇妙的算法-回文树最优化卷积判断的主要内容,如果未能解决你的问题,请参考以下文章

基于蜜蜂优化算法优化的卷积神经网络(CNN)图像分类

优化的图像卷积算法

SSE图像算法优化系列十八:三次卷积插值的进一步SSE优化。

Manacher算法模板

SSE图像算法优化系列十一:使用FFT变换实现图像卷积。

了解动态规划算法:原理实现和优化指南