HDOJ-ACM1015(JAVA) 运用 组合全排列实现

Posted xiezie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ-ACM1015(JAVA) 运用 组合全排列实现相关的知识,希望对你有一定的参考价值。

转载声明:原文转自:http://www.cnblogs.com/xiezie/p/5573934.html

 

这个题目的题意:(自己结合百度翻译,简单的翻译了一下)

“这个项目是在一个在二楼图书馆一幅画的背后的克莱因的保险箱里。克莱因的保险柜是极为罕见的;他们中的大多数都随着克莱因和他的工厂在二战中被摧毁。幸运的是,老布伦博在他死之前研究发现了克莱因的秘密并写下来了。一个克莱因保险箱有两个特点是:一个使用字母而不是数字的组合锁,和一个刻在门上的引用。克莱因的引用总是包含五个和十二个不同的大写字母之间,通常在句首,并提到了一个或多个数字。五种大写字母的形成了打开保险柜的密码。通过把所有的数字与适当的方式相结合,你将得到一个数字目标。(构造目标密码的细节)要找到组合,你必须选择五个字母,v, w, x, y, 和 z 并满足下面的方程,其中每一个字母被替换的顺序位置在字母组中(a= 1,b= 2,…,z= 26)。组合是vwxyz。如果有一个以上的解决方案则选择字典最大的组合,即,组合会出现在字典上的最后一个。”


v - w^2 + x^3 - y^4 + z^5 = target

例如,给定的目标1和字母abcdefghijkl,一个可能的解决方案是fiecb,6 - 9 ^ 2 + 5 ^ 3 - 3 ^ 4 + 2 ^ 5 = 1。其实在这种情况下的几种解决方案,但最终组合是lkeba。克莱因认为雕刻的编码组合是安全的,因为它可能需要几个月的努力,尝试所有的可能性,即使你知道这个秘密。当然,电脑那时不存在了。”

“开发一个程序,以寻找克莱因组合,以准备现场部署。按部门规定使用标准测试方法。输入包含一个或多个包含一个正整数目标低于一千二百万,并且至少五个最多十二个不同的大写字母。最后一行将包含一个零和字母的组合码 END 意味着输入结束。每行输出的克莱因组合是乱序的,如果没有正确的组合输出\'no solution\'。使用下面显示的精确格式。”

 

 

简单的题意是:

  从输入的字符串中,找出五个字母代替v、w、x、y、z,符合v - w^2 + x^3 - y^4 + z^5 = target 的所有答案中,输出最大的字符串。

我是思路是:获取长度为5的组合数,进行全排列并判断是否符合目标函数。

  因为做这道题,我把全组合和全排列算法实现了一遍。http://www.cnblogs.com/xiezie/p/5574516.html

注意:我偷了个懒,这道题我下面的代码可以优化,不过思路一样。

  可以不将结果存储起来,只需要实现字典序全排列,输出最后一个结果即可(将结果保存起来用字符串保存起来,一旦遇到下一个合适的字符串则替换)

 

以下是java实现:

import java.util.*;

import java.io.*;

public class Main1015{

    public static void main(String[] arg){
        Scanner scan = new Scanner(new BufferedInputStream(System.in));
        int target;
        String inputStr;
        ArrayList<String> answers  = new ArrayList<>();
        ArrayList<String> combinations = new ArrayList<>();
        ArrayList<Character> com = new ArrayList<>(5);
        while(true){
            target = scan.nextInt();
            inputStr = scan.next();
            if(target ==0 && inputStr.contentEquals("END")){
                break;
            }
            answers.clear();
            combinations.clear();
            com.clear();
            //获取所有的组合
            getCombinations(combinations,inputStr.toCharArray(),0,5,com);
            //获取全排列
            for(int i = 0 ; i != combinations.size() ; i ++ ){
                ArrayList<String> permutations = new ArrayList<>();
                getAllPermutations(permutations,combinations.get(i).toCharArray(),0,combinations.get(i).length());
                //判断是否符合target函数,符合则放入answer
                for(int j = 0 ; j != permutations.size() ; j ++){
                    if(target(permutations.get(j), target)){
                        answers.add(permutations.get(j));
                    }
                }
            }
            
            String answerCode = "" ;
            for(int i = 0 ; i != answers.size() ; i ++ ){
                if(answers.get(i).compareTo(answerCode)>=1){
                    answerCode = answers.get(i);
                }
            }
            if(answerCode.equals("")){
                System.out.println("no solution");
            }else{
                System.out.println(answerCode);
            }
        }
        scan.close();
    }
    
    static boolean target(String s,int target){
        char[] cs = s.toCharArray();
        return (cs[0]-\'A\'+1)-Math.pow(cs[1]-\'A\'+1,2)+Math.pow(cs[2]-\'A\'+1,3)-Math.pow(cs[3]-\'A\'+1,4)+Math.pow(cs[4]-\'A\'+1,5)==target;
    }
    
    static void getAllPermutations(ArrayList<String> answers,char[] cs,int start,int len){
        if(start == len ){
            answers.add(String.valueOf(cs));
            return;
        }
        for(int i = start ; i != len ; i ++){
            swap(cs,i,start);
            getAllPermutations(answers,cs,start+1,len);
            swap(cs,i,start);
        }
    }
    
    static void getCombinations(ArrayList<String> list ,char[] cs, int start,int len,ArrayList<Character> com){//len为组合的长度
        if(len == 0){
            String s = "";
            for(int i = 0 ; i != com.size() ; i ++){
                s = s.concat(com.get(i).toString());
            }
            list.add(s);
            return;
        }
        if(start==cs.length){
            return;
        }
        com.add(cs[start]);
        getCombinations(list,cs,start+1,len-1,com);
        com.remove(com.size()-1);
        getCombinations(list,cs,start+1,len,com);
    }
    
    static void swap(char[] cs , int i , int j){
        char t;
        t = cs[i];
        cs[i] = cs[j];
        cs[j] = t;
    }
}

 

以上是关于HDOJ-ACM1015(JAVA) 运用 组合全排列实现的主要内容,如果未能解决你的问题,请参考以下文章

HDOJ-ACM1012(JAVA)

HDOJ-ACM1013(JAVA)

HDOJ-ACM1014(JAVA)

HDOJ-ACM1022(JAVA)

HDOJ-ACM1071(JAVA) 定积分

HDOJ-ACM1002(JAVA实现 自定义大数处理类MBigInteger)