码迷,mamicode.com
首页 > 编程语言 > 详细

算法竞赛入门读书笔记(自用,慎入)

时间:2016-05-12 20:40:29      阅读:317      评论:0      收藏:0      [点我收藏+]

标签:

例3.2最长回文子串

技术分享

书中讲的很好,主要难点在三处
1. 输入字符串要含有空格,对应java下的readLine()方法即可
2. 查找回文串,暴力搜索,书中从中间搜索,没感觉复杂度降低多少
3. 原样输出,这就需要记录去除特殊符号后的串对应原串相应位置.(很常用的方法)

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int max = 0,x = 0,y = 0;//分别记录最大值,和对应原位置的下标
        String str = input.nextLine();
        int[] p = new int[str.length()];//记录原位置的数组
        char[] s = new char[str.length()];//记录去除特舒符号后的串
        //去除特殊符号并记录新数组中元素在原数组中位置
        for (int i = 0,m = 0; i < str.length(); i++) {
            if (Character.isLetter(str.charAt(i))) {
                p[m] = i;
                s[m++] = Character.toLowerCase(str.charAt(i));
            }
        }
        //开始查找回文串,利用StringBuilder的reverse来进行比较即可
        //基本思路就是暴力方法
        String strTemp = new String(s).trim();
        for (int i = 0; i < strTemp.length(); i++) {
            for (int j = i+1; j < strTemp.length(); j++) {
                StringBuilder builder = new StringBuilder(strTemp.substring(i, j));
                //当两者正反一致的时候说明为回文串
                if (builder.toString().equals(builder.reverse().toString())) {
                    if (j-i > max) {
                        max = j - i;
                        x = i;
                        y = j;
                    }
                }
            }
        }
        System.out.println(str.substring(p[x],p[y]));
    }
}

5.1.3周期串

技术分享

对于周期性问题,大多数都可以通过取余来得到一定的周期关系.对于定长字符串最好的操作还是转换成字符数组,方便修改和查找.

import java.util.Arrays;

public class Test2 {
    public static void main(String[] args) {
        String str = "aaa";
        char[] c = (str).toCharArray();
        //i的值实际上就是循环节的大小,故要从1开始,还可以避免除0
        for (int i = 1; i < c.length; i++) {
            boolean iscan = true;//标志变量
            if ((c.length) % i == 0) {//如果能整除i,则表示可能为当前这个子串
                for (int j = i; j < c.length; j++) {
                //因为是循环,这里利用取余来判断
                    if (c[j] != c[j%i]) {
                        iscan = false;
                        break;
                    }
                }
                if (iscan) {
                    System.out.println(i);
                }
            }
        }
        System.out.println(Arrays.toString(c));
    }
}

5.31 6174问题

技术分享
传统的学习循环,学习怎么取出数字的指定位数

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

public class Test3 {
    public static void main(String[] args) {
        //利用hash链表来存储每次计算产生的结果
        LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>();
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        map.put(n, n);
        int count = 0;
        //循环小于1000,也就是最多找1000个整数
        while(count <= 1000){
            int max = getNum(n, true);
            int min = getNum(n, false);
            n = max - min;
            //如果计算过了则退出
            if (map.containsKey(n)) {
                break;
            }
            map.put(n, n);
            count++;
        }
        System.out.println(map.toString()+"---"+n);
    }
    /**
     * 输入一个整数,计算出他正排和倒排的值
     * @param n
     * @param order true表示正排
     * @return
     */
    private static int getNum(int n,boolean order){
        int[] arr = new int[4];
        int i = 0;
        while(n>0){
            arr[i] = n % 10;
            n = n / 10;
            i++;
        }
        Arrays.sort(arr);
        if (order) {
            return arr[3]*1000+arr[2]*100+arr[1]*10+arr[0];
        }
        return arr[0]*1000+arr[1]*100+arr[2]*10+arr[3];
    }
}

5.31 字母重排

这里涉及了字符串的比较,一位一位的比较太过于繁琐,所以可以先排序后比较,就方便很多了

5.41 Cantor数表

这种找规律得题一般可以用技巧,先用预处理把一些可能用到计算的数据先保存起来,后面直接用,另外注意java里面写好的二分查找方法,很实用,还能自定义比较器

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

public class Test4 {
    public static void main(String[] args) {
        //预处理计算出前K项的和
        int arr[] = new int[1000];
        for (int i = 1; i < arr.length; i++) {
            arr[i] = (i+1)*i/2;
        }
        System.out.println(Arrays.toString(arr));
        //主程序开始
        Scanner input = new Scanner(System.in);
//      int n = input.nextInt();
        int n = 7;
        //二分查找,找到比这个数小的位置的k
        int mid = Arrays.binarySearch(arr, n);
        if (mid<0) {//如果没找到则返回插入位置,也就是第一个小于n得位置
            mid = -mid-1;//确定该元素是第mid+1斜线上的元素
            System.out.println((mid+1+n-arr[mid])+"/"+(arr[mid]-n+1));
        }else {//如果找到了则直接输出
            System.out.println(mid+"/"+(n-arr[mid]+1));
        }

    }
}

6.1.1卡片游戏

技术分享
主要是java队列得简单用法,代码很清晰,另外这是双端队列,可以直接操作队头或者队尾

import java.util.ArrayDeque;

public class Test5 {

    public static void main(String[] args) {
        //构造一个初始容量为10得队列
        ArrayDeque<Integer> queue = new ArrayDeque<>(10);
        //对于队列一般实用offer,poll,peek等方法,这几个可以通过返回值判断是否成功
        for (int i = 1; i < 8; i++) {
            queue.offer(i);
        }
        while(!queue.isEmpty()){
            System.out.println(queue.pollFirst());;
            if (queue.peek() != null) {
                queue.offer(queue.poll());
            }
        }
    }
}

6.3.1小球下落

对于二叉树得数组表示法,因为知道了深度就知道二叉树总节点数,因为二叉树本身是等比数列,可以用1<<D来表示其节点数,而且如果按从上到下从左到右排序得话,节点k得左孩子是2k,右孩子是2k+1
技术分享

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

public class Test6 {

    public static void main(String[] args) {
        int D,I;
        Scanner input = new Scanner(System.in);
        D = input.nextInt();
        I = input.nextInt();
        boolean[] s = new boolean[1<<D];//s[0]不用
        for (int j = 0; j < I; j++) {//对小球循环
            //每一个小球滚落模拟
            int j2 = 1;
            for (; ;) {
                s[j2] = !s[j2];//转动开关
                if (s[j2]) {//关闭向左
                    j2 = 2*j2;
                }else {//开启向右
                    j2 = 2*j2+1;

                }
                if (j2 > s.length-1) {
                    break;
                }
            }
            System.out.println(j2/2);//除以2找到最后经过的节点

        }
        System.out.println(Arrays.toString(s));
    }
}

算法竞赛入门读书笔记(自用,慎入)

标签:

原文地址:http://blog.csdn.net/u012706811/article/details/51351813

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!