AOJ1252 Confusing Login Names
問題リンク Confusing Login Names
- 概要
N人の名前と整数Dが与えられる。N人の中で混乱する名前の対を全て求めよ。
混乱する名前の対(i, j)とは、
任意の1文字を消す
任意の位置に文字を1字入れる
任意の1文字を別の文字にする
隣接している文字同士を1か所交換する
のいずれかの操作をD回以下行ってiからjの名前が得られるようなものをいう。名前に使われる文字はアルファベットの小文字のみである。
0 < N <= 200
1 <= D <= 2
名前の長さ < 16
- 解法
ある名前から操作を1回行って得られる文字列は 16+16*26+16*26+16 = 864 通りあります。ある名前に操作を2回施して得られる名前はさらに864通りの組み合わせがあるのでおよそ10^6オーダーになります。これが最大200人いるので10^8オーダーの名前が出来てしまいます。
実は、N人の名前にそれぞれ操作を1回施した結果が求まっていれば事足ります。i番目の名前から操作を1回施して得られた文字列の集合をs[i]とおきます。
名前iとjが混乱する対かどう判定するか説明します。
D=1のとき、iがs[j]に含まれていれば混乱対です。
D=2のとき、iがs[j]に含まれているかs[i]のいずれかがs[j]に含まれていれば混乱対です。
- ソース
import java.util.HashSet; import java.util.PriorityQueue; import java.util.Scanner; import java.util.Set; //Confusing Login Names public class AOJ1252 { Set<String>[] s; class P implements Comparable<P>{ String s, t; public P(String s, String t) { this.s = s.compareTo(t)<0?s:t; this.t = s.compareTo(t)<0?t:s; } public int compareTo(P o) { return s.equals(o.s)?t.compareTo(o.t):s.compareTo(o.s); } } void make(int i, String v){ int n = v.length(); StringBuffer f = new StringBuffer(v); //delete for(int j=0;j<n;j++){ char ch = f.charAt(j); f.deleteCharAt(j); s[i].add(f.toString()); f.insert(j, ch); } //insert for(int j=0;j<=n;j++){ for(char ch='a';ch<='z';ch++){ f.insert(j, ch); s[i].add(f.toString()); f.deleteCharAt(j); } } //replace for(int j=0;j<n;j++){ char ch = f.charAt(j); for(char c='a';c<='z';c++){ f.setCharAt(j, c); s[i].add(f.toString()); } f.setCharAt(j, ch); } //swap for(int j=0;j<n-1;j++){ char a = f.charAt(j), b = f.charAt(j+1); f.setCharAt(j, b); f.setCharAt(j+1, a); s[i].add(f.toString()); f.setCharAt(j, a); f.setCharAt(j+1, b); } } @SuppressWarnings("unchecked") void run(){ Scanner sc = new Scanner(System.in); for(;;){ int n = sc.nextInt(); if(n==0)break; int d = sc.nextInt(); s = new HashSet[n]; String[] name = new String[n]; for(int i=0;i<n;i++){ name[i] = sc.next(); s[i] = new HashSet<String>(); make(i, name[i]); } PriorityQueue<P> q = new PriorityQueue<P>(); for(int i=0;i<n;i++)for(int j=i+1;j<n;j++){ if(d==1){ if(s[i].contains(name[j]))q.add(new P(name[i], name[j])); } else{ if(s[i].contains(name[j]))q.add(new P(name[i], name[j])); else{ for(String v:s[i])if(s[j].contains(v)){ q.add(new P(name[i], name[j])); break; } } } } int r = q.size(); while(!q.isEmpty()){ P p = q.poll(); System.out.println(p.s+","+p.t); } System.out.println(r); } } public static void main(String[] args) { new AOJ1252().run(); } }