Anagramic squares

By replacing each of the letters in the word CARE with 1, 2, 9, and 6 respectively, we form a square number: 1296 = 362. What is remarkable is that, by using the same digital substitutions, the anagram, RACE, also forms a square number: 9216 = 962. We shall call CARE (and RACE) a square anagram word pair and specify further that leading zeroes are not permitted, neither may a different letter have the same digital value as another letter.

Using words.txt (right click and ‘Save Link/Target As…’), a 16K text file containing nearly two-thousand common English words, find all the square anagram word pairs (a palindromic word is NOT considered to be an anagram of itself).

What is the largest square number formed by any member of such a pair?

NOTE: All anagrams formed must be contained in the given text file.


重排平方数

将单词CARE中的四个字母依次赋值为1、2、9、6,我们得到了一个平方数:1296 = 362。神奇的是,使用同样的数字赋值,重排后的单词RACE同样构成了一个平方数:9216 = 962。我们称CARE和RACE为重排平方单词对,同时规定这样的单词对不允许有前导零或是不同的字母赋相同的值。

在这个16K的文本文件words.txt(右击并选择“目标另存为……”)中包含了将近两千个常见英文单词,找出所有的重排平方单词对(一个回文单词不视为它自己的重排)。

重排平方单词对所给出的最大平方数是多少?

注意:所有的重排单词必须出现在给定的文本文件中。

解题

 先说下自己的思路:

1.words文件中找出又相同字母组成的单词对

2.构造平方数,筛选由相同数字组成的平方数

3.关键的就是单词和数字的映射关系,特别是位置要做到对应,但是我只能保证字母和数字映射后,可以组成的数字是平方数,但是数字的顺序字母映射的顺序不一样,造成输出的结果比较多。

Java

package Level3;

import java.io.BufferedReader;

import java.io.FileReader;
import java.io.IOException;

import java.util.ArrayList;
import java.util.HashMap;


public class PE098{
    
    // 下面结果输出的比较多,其实求最大值也是不对的,但是但是,答案就在输出的结果中
    // 输出的两个单词由相同字母组成,输出的两个数字是两个平方数并且含有相同的数字,但是但是,两个单词字母的位置和数字的位置不是对应的
    // 如果能够让他们一一对应,答案应该就是唯一的了。在对两个单词和数字匹配的时候,程序还需要完善
    public static void run() throws IOException{
        // 相同字母的单词对
        ArrayList<ArrayList<String>> dicts = getAnagramic();
        // 相同数字的平方数 
        ArrayList<ArrayList<Integer>> anagNum = AnagNum();
        for(int i=0;i<dicts.size();i++){
            ArrayList<String> dict = new ArrayList<String>();
            dict = dicts.get(i);
            for(int j=0;j<anagNum.size();j++){
                ArrayList<Integer> num = new ArrayList<Integer>();
                num = anagNum.get(j);
                if(isReplace(dict.get(0),dict.get(1),num.get(0)) && isReplace(dict.get(1),dict.get(0),num.get(1)))
                    System.out.println(dict.get(0)+"\t"+dict.get(1)+"\t"+num.get(0)+"\t" + num.get(1));
            }
        }
    }
    // str1 str2 是相同字母组成的单词,看看是否都和num可以匹配
    public static boolean isReplace(String str1,String str2,int num1){
        int strlen = str1.length();
        int numlen = String.valueOf(num1).length();
        if(numlen!= strlen)
            return false;
        int[] A = new int[strlen];
        String[] B = new String[10];
        int tmp = num1;
        HashMap<Character,Integer> mapraw = new HashMap<Character,Integer>();
        HashMap<Character,Integer> mapall = new HashMap<Character,Integer>();
        for(int i=strlen-1;i>=0;i--){
            char ch = str1.charAt(i);
            //相同字母不能有相同的value
            if(mapraw.containsValue(num1%10) == true)
                return false;
            mapraw.put(ch, num1%10);
            if(mapall.containsKey(ch)==false)
                mapall.put(ch, num1%10);
            else{
                mapall.put(ch, mapall.get(ch)+num1%10);
            }
            num1/=10;
        }
        for(int i=0;i<strlen;i++){
            char ch = str2.charAt(i);
            if(mapall.containsKey(ch) == false)
                return false;
            else{
                mapall.put(ch,mapall.get(ch) - mapraw.get(ch));
            }
        }
        for(int i=0;i<strlen;i++){
            char ch = str1.charAt(i);
            int value = mapall.get(ch);
            if(value!=0)
                return false;
        }
        // 上面的程序只是判断了str1 和num1进行映射后 str2也可以这样搞,
        return true;

        
    }
    // 获取相同数字的平方数对 
    public static ArrayList<ArrayList<Integer>> AnagNum(){
        ArrayList<ArrayList<Integer>> anagNum = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> squares = new ArrayList<Integer>();
        int MAX = 999999;
        int i = 11;
        // 构造平方数
        while(true){
            if(i*i>=MAX)
                break;
            squares.add(i*i);
            i++;
        }
        //寻找相同数字的数
        for(i=0;i<squares.size();i++){
            int num1 = squares.get(i);
            
            for(int j=i+1;j<squares.size();j++){
                int num2 = squares.get(j);
                if(isDiff(num1,num2)){
                    // 相同数字的平方数,两个两个数的保存
                    ArrayList<Integer> num = new ArrayList<Integer>();
                    num.add(num1);
                    num.add(num2);
                    anagNum.add(num);
                }
                
            }
        }

//        System.out.println(anagNum.size());
//        for(i=0;i<anagNum.size();i++){
//            ArrayList<Integer> num = new ArrayList<Integer>();
//            num = anagNum.get(i);
//            for(int j =0;j<num.size();j++){
//                System.out.print(num.get(j)+"\t");
//            }
//            System.out.println();
//        }

        return anagNum;
    }


    public static ArrayList<ArrayList<String>> getAnagramic() throws IOException {
        ArrayList<String> words = getWords();
        ArrayList<ArrayList<String>> dicts = new ArrayList<ArrayList<String>>();
        //暴力遍历,找到相同字母的单词
        for(int i=0;i<words.size();i++){
            String tmp1 = words.get(i);
            
            for(int j=i+1;j<words.size();j++){
                String tmp2 = words.get(j);
                if(isDiff(tmp1,tmp2)){
                    // 相同字母的单词,两个两个的保存
                    ArrayList<String> dict = new ArrayList<String>();
                    dict.add(tmp1);
                    dict.add(tmp2);
                    dicts.add(dict);
                }
            }
            // 相同字母单词的个数 大于 1
//            if(dict.size()>=2)
//                dicts.add(dict);
        }
        int size = dicts.size();
        // 输出相同字母的单词对 
//        for(int i=0;i<dicts.size(); i++){
//            ArrayList<String> dict = new ArrayList<String>();
//            dict = dicts.get(i);
//            for(int j=0;j<dict.size();j++){
//                System.out.print(dict.get(j)+"\t");
//            }
//            System.out.println();
//        }
//        System.out.println(size);
        return dicts;
    }
    // 读取单词表
    public static ArrayList<String> getWords() throws IOException{
        String filename = "src/Level3/p098_words.txt";
        ArrayList<String> words = new ArrayList<String>();
        BufferedReader reader = new BufferedReader(new FileReader(filename));
        String data = reader.readLine();
        data = data.replace("\"", "");
//        System.out.println(data);
        String[] dictArray = data.split(",");
        for(int i=0;i<dictArray.length;i++){
//            System.out.println(dictArray[i]);
            words.add(dictArray[i]);
        }
//        System.out.println(dictArray.length);

        return words;
    }
    public static boolean isDiff(String str1,String str2){
        int len1 = str1.length();
        int len2 = str2.length();
        if(len1!=len2)
            return false;
        int diff[] = new int[26];
        for(int i=0;i<len1;i++){
            diff[str1.charAt(i) - 'A']++;
            diff[str2.charAt(i) - 'A']--;
        }
        for(int i=0;i<26;i++)
            if(diff[i]!=0)
                return false;
        return true;
    }
    public static boolean isDiff(int num1,int num2){
        
        int len1 = (num1+"").length();
        int len2 = (num2+"").length();
        if(len1!=len2)
            return false;
        int diff[] = new int[10];
        while(num1!=0 ||num2!=0){
            diff[num1%10]++;
            diff[num2%10]--;
            num1/=10;
            num2/=10;
        }
        for(int i=0;i<10;i++)
            if(diff[i]!=0)
                return false;
        return true;
    }
    public static void main(String[] args) throws IOException {
        long t0 = System.currentTimeMillis();
        run();
        long t1 = System.currentTimeMillis();
        long t = t1 - t0;
        System.out.println("running time="+t/1000+"s"+t%1000+"ms");

    }
}
View Code

相关文章:

  • 2022-12-23
  • 2021-12-01
  • 2021-07-17
  • 2021-10-01
  • 2021-05-22
  • 2022-02-09
  • 2021-09-05
  • 2021-07-28
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-08-02
  • 2021-06-07
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案