海贼007

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

【题意】将字符串A变成字符串B,两种操作:Next,将字符置换成下一个字符('a'>'b','b'>'c'...'y'>'z');Prev,将字符置换成前一个字符('z'>'y','y'>'x'...'b'>'a')。Next和Prev操作的代价不同,求出最小代价,如果不行则返回-1。

【算法】:
1.判断能否由A得到B。如果不能,return -1;
  如何判断:可以建立一个二部图。左右两侧的点依次为a、b、c...y、z。(A[i],B[i])代表二部图中的一条边,任意两条边有相交,则A不能得到B。因此判断条件是(A[i]-A[j])*(B[i]-B[j])不能为负,for any i,j。
2.计算代价。

【Java代码】来自菜鸟

 1 import java.util.*;
 2 import java.util.regex.*;
 3 import java.text.*;
 4 import java.math.*;
 5 
 6 
 7 public class NextOrPrev
 8 {
 9     public int getMinimum(int nextCost, int prevCost, String start, String goal)
10     {
11         char[] s = start.toCharArray();
12         char[] g = goal.toCharArray();
13         
14         //check if we can get to goal
15         int i,j;
16         for(i=0;i<s.length;i++){
17             for(j=i+1;j<s.length;j++){
18                 if((s[i]-s[j])*(g[i]-g[j])<0)
19                     return -1;
20             }
21         }
22         //compute
23         int count=0;
24         for(i=0;i<s.length;i++){
25             if(s[i]<g[i]){
26                 count+=nextCost*(g[i]-s[i]);
27             }
28             else{
29                 count+=prevCost*(s[i]-g[i]);
30             }
31         }
32         
33         return count;
34     }
35     
36 
37 }
38 //Powered by KawigiEdit 2.1.4 (beta) modified by pivanof!
View Code

【Java代码】来自大神

【分析】他给A[i],B[i]排了序,反映到二部图上来,也是不能有边相交。

public class NextOrPrev {
 
  public int getMinimum(int nextCost, int prevCost, String start, String goal) {
    int length = start.length();
    int[] alignStart = new int[length];
    int[] alignGoal = new int[length];
    int i;
    int cost = 0;
    
    
    i = 0;
    for(char c = 'a'; c <= 'z'; c++) {
      for(int j=0; j<length; j++) {
        if (start.charAt(j) == c) {
          alignStart[j] = i++;
          break;
        }
      }
    }
 
    i = 0;
    for(char c = 'a'; c <= 'z'; c++) {
      for(int j=0; j<length; j++) {
        if (goal.charAt(j) == c) {
          alignGoal[j] = i++;
          break;
        }
      }
    }
    
    for(int j=0; j<length; j++) {
      int dist;
      
      if(alignStart[j] != alignGoal[j]) {
        return -1;
      }
      dist = start.charAt(j) - goal.charAt(j);
      
      cost += dist < 0 ? nextCost * dist * -1 : prevCost * dist;  
    }
    
    
    
    return cost;
  }
 
}
View Code

【C++代码】来自大神

【分析】大神的判断条件,在二部图上反映出来也是两条边不能相交。但不知道大神是否也是用二部图来分析的,是否有更好的想法?

#include<vector>
#include<string>
#include<algorithm>
using namespace std;
 
class NextOrPrev{
  public:
  int getMinimum(int ne,int pr,string st,string go){
    int i,j,k,n;
    n=st.length();
    for(i=0;i<n;i++)
      for(j=0;j<n;j++)
        if((st[i]<st[j] && go[i]>go[j]) || (st[i]>st[j] && go[i]<go[j]))
          return -1;
    int ans=0;
    for(i=0;i<n;i++)
      if(st[i]<go[i])ans+=(((int)go[i])-((int)st[i]))*ne;
      else ans+=(((int)st[i])-((int)go[i]))*pr;
    return ans;
  }
};
View Code

【总结】:通过看大神的代码,自己YY出来的二部图模型,不知道有没有更好的方法。

posted on 2013-07-28 23:06  wzhscript  阅读(249)  评论(0编辑  收藏  举报