码迷,mamicode.com
首页 > 其他好文 > 详细

稍大的串—题解

时间:2015-05-22 22:40:03      阅读:352      评论:0      收藏:0      [点我收藏+]

标签:稍大的串   康拓展开   

标题:稍大的串


  串可以按照字典序进行比较。例如:
  abcd 小于 abdc


  如果给定一个串,打乱组成它的字母,重新排列,可以得到许多不同的串,在这些不同的串中,有一个串刚好给定的串稍微大一些。科学地说:它是大于已知串的所有串中最小的串。你的任务就是求出这个“稍大的串”。


例如:
输入串:
abfxy
程序应该输出:
abfyx


再例如:
输入串:
ayyyxxff
程序应该输出:
fafxxyyy


数据规模约定:
  输入的串不超过1000个字符。


特例:
  如果已知的串已经是所有重组串中最大的,则原样输出读入的那个串。




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




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


所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。

注意:主类的名字必须是:Main,否则按无效代码处理。


解题思路: 刚开始想的是,利用康拓展开的逆运算去解决,最后发现大数据过不了。由于我们只需要求出一个序列的下一个,就直接模拟吧!


方法一:大数据无感

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;

/**
 * 
 *  康拓展开 
 *
 */

public class Main2
{
	public static BigInteger[]dp = new BigInteger[1000];
	public static void main(String[] args)
	{
		long t = System.nanoTime();
        Scanner sc = new Scanner(System.in);
	    String str = sc.nextLine();
	    // 初始
	    init();
	    char c[] = str.toCharArray();
	    Arrays.sort(c);
	    
	    if (str.equals(new StringBuffer(String.valueOf(c)).reverse().toString()))
         System.out.println(str);
	    else
	    {
	    	long result = getHash(str.toCharArray());
	    	String s = reverHash(++result, c);
	    	while (s.compareTo(str)<=0)
	    	{
	    		s = reverHash(++result, c);
	    	}
	    	System.out.println(s);
	    }
	    System.out.println(System.nanoTime() - t + " ns");
	}
	
	private static String reverHash(long num, char[] c)
	{
	    boolean step[] = new boolean[c.length];
	    StringBuffer sb = new StringBuffer();
	    int j,k;
	    for (int i = 0; i < c.length; i++)
	    {
	    	long temp = num / dp[c.length-1-i].longValue();
	    	num -= temp * dp[c.length-1-i].longValue();
	    	for (j=0,k=0; k <= temp; j++)
	    	{
	    		if (!step[j]) k++;
	    	}
	    	step[j-1] = true;
	    	sb.append(c[j-1]);
	    }
		return sb.toString();
	}

	private static long getHash(char[] c)
	{
		long sum = 0;
		for (int i = 0; i < c.length; i++)
		{
		    long count = 0;
		    for (int j = i+1; j < c.length; j++)
		    	if (c[i] > c[j]) count++;
			sum += count * dp[c.length-1-i].longValue();
		}
		return sum;
	}
	
	private static void init()
	{
		BigInteger b1 = new BigInteger("1");
		dp[0]=dp[1]=BigInteger.ONE; 
        for (int i = 2; i < 1000; i++)
        {
       	  b1 = b1.multiply(BigInteger.valueOf(i)); 
       	  dp[i]= new BigInteger(b1.toString());
        }
	}
}

方法二: 完美

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



public class Main6
{
    public static void main(String[] args)
	{
    	Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        char c1[] = str.toCharArray();
        char c2[] = null;
        boolean flag = false;
        
        for (int i = c1.length-1; i > 1; i--)
        {
        	if (c1[i] > c1[i-1])
        	{
        		char temp = c1[i];
        		c1[i] = c1[i-1];
        		c1[i-1] = temp;
        		c2 = new char[c1.length-i];
        		System.arraycopy(c1, i, c2, 0, c2.length);
        		Arrays.sort(c2);
        		flag = true;
        		break;
        	}
        	if (flag) break;
        }
        
        // 一般情况匹配成功
        if (flag)
        {
        	for (int i = 0; i < c1.length-c2.length; i++)
        		System.out.print(c1[i]);
        	for (int i = 0; i < c2.length; i++)
        		System.out.print(c2[i]);
        	System.out.println();
        }
        else
        {
        	// 类似  19876 这样的字符串,还有 29872这样的
        	if (str.length() > 1 && c1[0] < c1[1])
        	{
        		int t = -1;
        	    for (int i = str.length()-1; i>0 ; i--) if (c1[0] < c1[i]){ t = i; break;}
        			char temp = c1[0];
        			c1[0] = c1[t];
        			c1[t] = temp;
        			
        			c2 = new char[c1.length-1];
        			System.arraycopy(c1, 1, c2, 0, c2.length);
        			Arrays.sort(c2);
        			for (int i = 0; i < c1.length-c2.length; i++)
        				System.out.print(c1[i]);
        			for (int i = 0; i < c2.length; i++)
        				System.out.print(c2[i]);
        			System.out.println();
        	}
        	// 特例
        	else
        		System.out.println(str);
        }
        
	}
}


稍大的串—题解

标签:稍大的串   康拓展开   

原文地址:http://blog.csdn.net/first_sight/article/details/45920191

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