zoukankan      html  css  js  c++  java
  • java实现第六届蓝桥杯切开字符串

    切开字符串

    Pear有一个字符串,不过他希望把它切成两段。
    这是一个长度为N(<=10^5)的字符串。
    Pear希望选择一个位置,把字符串不重复不遗漏地切成两段,长度分别是t和N-t(这两段都必须非空)。

    Pear用如下方式评估切割的方案:
    定义“正回文子串”为:长度为奇数的回文子串。
    设切成的两段字符串中,前一段中有A个不相同的正回文子串,后一段中有B个不相同的非正回文子串,则该方案的得分为A*B。

    注意,后一段中的B表示的是:“…非正回文…”,而不是: “…正回文…”。
    那么所有的切割方案中,A*B的最大值是多少呢?

    【输入数据】
    输入第一行一个正整数N(<=10^5)
    接下来一行一个字符串,长度为N。该字符串仅包含小写英文字母。
    【输出数据】
    一行一个正整数,表示所求的A*B的最大值。
    【样例输入】
    10
    bbaaabcaba
    【样例输出】
    38
    【数据范围】
    对于20%的数据,N<=100
    对于40%的数据,N<=1000
    对于100%的数据,N<=10^5

    资源约定:
    峰值内存消耗(含虚拟机) < 512M
    CPU消耗 < 2000ms

    请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

    所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
    注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
    注意:主类的名字必须是:Main,否则按无效代码处理。

    以下代码对于N大于10000可能会超时,代码仅供参考。
    import java.util.HashSet;
    import java.util.Scanner;
    
    public class Main {
        public static String A, S;
        
        public int Manacher(String M, String N) {
            int count = 0;  //统计字符串M中不同正回文串个数
            int[] P = new int[M.length()];
            int mx = 0, id = 0;
            for(int i = 1;i < M.length();i++) {
                if(mx > i)
                    P[i] = Math.min(P[2 * id - i], mx - i);
                else
                    P[i] = 1;
                while(i+P[i] < M.length() && i-P[i] >= 0 && 
                        M.charAt(i+P[i]) == M.charAt(i-P[i]))
                    P[i]++;
                if(P[i] + i > mx) {
                    mx = i + P[i];
                    id = i;
                }
            }
            HashSet<String> set = new HashSet<String>();
            for(int i = 2;i < P.length;i = i + 2) {
                int len = P[i] - 1;
                int j = i / 2 - 1;  //回文串中心字符在字符串N中的位置
                if(len == 0) {
                    String s = N.substring(j, j + 1);
                    if(!set.contains(s)) {
                        set.add(s);
                        count++;
                    }
                } else if(len % 2 == 1){
                    for(int k = 0;k <= len / 2;k++) {
                        String s = N.substring(j - k, j + k + 1);
                        if(!set.contains(s)) {
                            set.add(s);
                            count++;
                        }
                    }
                }
            }
            return count;
        }
        
        public int getAllChildern(String M) {
            int count = 0;  //统计字符串M所有不同子串个数
            HashSet<String> set = new HashSet<String>();
            for(int i = 0, len = 1;i < M.length();i++, len++) {
                for(int j = 0;j <= M.length() - len;j++) {
                    String s = M.substring(j, j + len);
                    if(!set.contains(s)) {
                        set.add(s);
                        count++;
                    }
                }
            }
            return count;
        }
        
        public void getResult() {
            int max = -1;
            for(int i = 1;i < A.length() - 1;i++) {
                String s1 = S.substring(0, i * 2 + 1);
                String s2 = "$" + S.substring(i * 2 + 1);
                String s3 = A.substring(0, i);
                String s4 = A.substring(i);
                int a = Manacher(s1, s3);
                int b = getAllChildern(s4) - Manacher(s2, s4);
                max = Math.max(max, a * b);
            }
            System.out.println(max);
        }
        
        public static void main(String[] args) {
            Main test = new Main();
            Scanner in = new Scanner(System.in);
            A = in.next();
            StringBuilder s1 = new StringBuilder("$#");
            for(int i = 0;i < A.length();i++) {
                s1.append(A.charAt(i));
                s1.append("#");
            }
            S = s1.toString();
            test.getResult();
        }
    }
    

    PS:纯暴力

    package 第七次模拟;
    
    import java.util.HashSet;
    import java.util.Scanner;
    import java.util.Set;
    
    public class Demo8切开字符串 {
    	static int n;
    	static String str = new String();
    	static int max = 0;
    	static int A, B, C;
        public static void main(String[] args) {
    		Scanner in = new Scanner(System.in);
    		n = in.nextInt();
    		str = in.next();
    		for (int t = 1; t < n-1; t++) {
    			A = panduan(str.substring(0, t));
    			B = quan(str.substring(t, n)) - panduan(str.substring(t, n));
    			if (max < A*B) {
    				max = A*B;
    			}
    		}
    		System.out.println(max);
    	}
        /**
         * B的要求是找出 不相同的非正回文子串 这里采用曲线救国的方案,求出B的 全部不相同子串 的个数,减去B中 不相同的正回文子串 的个数
         * 
         * */
    	private static int quan(String sub) {
    		// TODO Auto-generated method stub
    		Set<String> set = new HashSet<String>();
    		for (int i = 1; i <= sub.length(); i++) {
    			for (int start = 0; start <= sub.length()-i; start++) {
    				String s = sub.substring(start, start+i);
    				set.add(s);
    			}
    		}
    		return set.size();
    	}
    	/**
    	 * 对于一个字符串,查找其中包含的正回文串个数
    	 * */
    	private static int panduan(String sub) {
    		// TODO Auto-generated method stub
    		Set<String> set = new HashSet<String>();
    		set.clear();
    		for (int i = 1; i <= sub.length(); i+=2) {
    			for (int start = 0; start <= sub.length()-i; start++) {
    				String s = sub.substring(start, start+i);
    				if (huiwen(s) == true) {
    					set.add(s);
    				}
    			}
    		}
    		return set.size();
    	}
    	/**
    	 * 判断回文
    	 * */
    	private static boolean huiwen(String s) {
    		// TODO Auto-generated method stub
    		for (int i = 0; i < s.length()/2; i++) {
    			if (s.charAt(i) == s.charAt(s.length()-1-i)) {
    				continue;
    			} else {
    				return false;
    			}
    		}
    		return true;
    	}
    
    
    }
    
    
  • 相关阅读:
    状态压缩 + 暴力 HDOJ 4770 Lights Against Dudely
    简单几何(推公式) UVA 11646 Athletics Track
    简单几何(四边形形状) UVA 11800 Determine the Shape
    简单几何(求交点) UVA 11437 Triangle Fun
    计算几何模板
    简单几何(相对运动距离最值) UVA 11796 Dog Distance
    简单几何(求划分区域) LA 3263 That Nice Euler Circuit
    覆盖的面积 HDU
    Desert King 最小比率生成树 (好题)
    约会安排 (区间合并)毒瘤题
  • 原文地址:https://www.cnblogs.com/a1439775520/p/13077189.html
Copyright © 2011-2022 走看看