【题意】:给你两个数A、B,问从A得到B最少需要的步数,怎么走这样规定:可以A/10得到一个数,或者翻转A得到一个数。如果不能则输出-1;
【算法】
1.找出A中的B,计算步数。
2.找出A中B的逆串,计算并更新最优解。
3.输出最优解。
【编码调试BUG】
1.18行,A中可能不存在B,所以要考虑indexOf返回-1的情况。
【Java代码】来自菜鸟
1 import java.util.*; 2 import java.util.regex.*; 3 import java.text.*; 4 import java.math.*; 5 6 7 public class TheNumberGameDiv2 8 { 9 public int minimumMoves(int A, int B) 10 { 11 String strA = ""+A; 12 String strB = ""+B; 13 int count1=Integer.MAX_VALUE,count2=Integer.MAX_VALUE; 14 int left,right; 15 16 //compute steps if B is in A 17 left = strA.indexOf(strB); 18 if(left!=-1){ 19 right = strA.length() - left - strB.length(); 20 21 if(left==0){ 22 count1 = right; 23 }else{ 24 count1 = right+left+2; 25 } 26 } 27 28 //compute steps if inverse B is in A 29 StringBuilder sb = new StringBuilder(strB); 30 sb.reverse(); 31 strB = sb.toString(); 32 33 left = strA.indexOf(strB); 34 if(left!=-1){ 35 right = strA.length() - left - strB.length(); 36 37 if(left==0){ 38 count2 = right+1; 39 }else{ 40 count2 = right+left+1; 41 } 42 } 43 44 return Math.min(count1, count2)==Integer.MAX_VALUE?-1:Math.min(count1, count2); 45 } 46 47 48 } 49 //Powered by KawigiEdit 2.1.4 (beta) modified by pivanof!
【改进版代码】
【分析】
1.步数只需要考虑两点:a,A比B长多少;b,是否需要翻转A。所以不需要初始版本中的left和right。
2.学习了大神对StringBuilder求逆串的使用方法。
1 import java.util.*; 2 import java.util.regex.*; 3 import java.text.*; 4 import java.math.*; 5 6 7 public class TheNumberGameDiv2 8 { 9 public int minimumMoves(int A, int B) 10 { 11 String strA = ""+A; 12 String strB = ""+B; 13 int count1=Integer.MAX_VALUE,count2=Integer.MAX_VALUE; 14 int index; 15 16 //compute steps if B is in A 17 index = strA.indexOf(strB); 18 if(index!=-1){ 19 count1=strA.length() - strB.length(); 20 if(index!=0){ 21 count1+=2; 22 } 23 } 24 25 //compute steps if inverse B is in A 26 strB = new StringBuilder().append(strB).reverse().toString(); 27 index = strA.indexOf(strB); 28 if(index!=-1){ 29 count2 = strA.length() - strB.length()+1; 30 } 31 32 return Math.min(count1, count2)==Integer.MAX_VALUE?-1:Math.min(count1, count2); 33 } 34 35 // 36 } 37 //Powered by KawigiEdit 2.1.4 (beta) modified by pivanof!
【Java代码】来自大神
【分析】算法不同,还没有看出来是什么算法。
1 import java.util.LinkedList; 2 import java.util.HashSet; 3 4 public class TheNumberGameDiv2 { 5 6 public int minimumMoves(int A, int B) { 7 HashSet<Integer> seen = new HashSet<Integer>(); 8 9 10 LinkedList<TheNumberGameDiv2.state> q = new LinkedList<TheNumberGameDiv2.state>(); 11 q.add(new state(A, 0)); 12 seen.add(A); 13 while (!q.isEmpty()){ 14 state s = q.poll(); 15 if (s.a == B)return s.time; 16 if (!seen.contains(s.a/10)){ 17 seen.add(s.a/10); 18 q.add(new state(s.a/10,s.time+1)); 19 } 20 int r = reverse(s.a); 21 if (!seen.contains(r)){ 22 seen.add(r); 23 q.add(new state(r,s.time+1)); 24 } 25 26 } 27 28 return -1; 29 } 30 public int reverse (int a){ 31 return Integer.valueOf(new StringBuilder().append(a).reverse().toString()); 32 } 33 public static class state{ 34 35 int a; 36 int time; 37 public state(int a, int time){ 38 this .a = a; 39 this.time = time; 40 } 41 } 42 }
【C++代码】来自大神
【分析】算法不同,貌似用到了DP?
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #include <numeric> 5 #include <climits> 6 #include <bitset> 7 #include <string> 8 #include <iostream> 9 #include <set> 10 #include <map> 11 #include <cstdio> 12 #include <cstdlib> 13 #include <list> 14 #include <cstring> 15 #define mod 1000000007 16 using namespace std; 17 map <long long, long long> m; 18 class TheNumberGameDiv2 19 { 20 private: 21 long long a; 22 long long b; 23 long long f (long long x) 24 { 25 if (x == b) { 26 return 0; 27 } 28 if (m[x] != 0) { 29 return m[x]; 30 } 31 long long y = 0,mm; 32 mm = 100000000LL; 33 m[x] = mm; 34 mm = min (mm, 1 + f (x/10)); 35 long long xx = x; 36 while (x != 0) { 37 y = y*10 + (x%10); 38 x = x/10; 39 } 40 mm = min (mm, 1 + f(y)); 41 42 return m[xx]=mm; 43 } 44 45 public: 46 int minimumMoves(int A, int B) 47 { 48 this -> a = A; 49 this -> b = B; 50 long long x; 51 x = f (a); 52 if (x >= 100000000LL) { 53 return -1; 54 } 55 return x; 56 } 57 };
【总结】
算法是多种多样的,大神站得高看得远,DP什么的信手拈来,还需多多学习。