貪心演算法-翻硬幣
阿新 • • 發佈:2019-02-09
問題描述
小明正在玩一個“翻硬幣”的遊戲。
桌上放著排成一排的若干硬幣。我們用 * 表示正面,用 o 表示反面(是小寫字母,不是零)。
比如,可能情形是:**oo***oooo
如果同時翻轉左邊的兩個硬幣,則變為:oooo***oooo
現在小明的問題是:如果已知了初始狀態和要達到的目標狀態,每次只能同時翻轉相鄰的兩個硬幣,那麼對特定的局面,最少要翻動多少次呢?
我們約定:把翻動相鄰的兩個硬幣叫做一步操作,那麼要求:
輸入格式
兩行等長的字串,分別表示初始狀態和要達到的目標狀態。每行的長度<1000
輸出格式
一個整數,表示最小操作步數。
樣例輸入1
o****o****
樣例輸出1
5
樣例輸入2
o**o***o**
o***o**o**
樣例輸出2
1
思路
貪心題。 我的思路是先對兩個字串進行比較,用陣列記錄下比較的結果,0表示字元相同,1表示字元不同。 用題目給的例子示範:
比較結果為:
1000010000
翻動次數就是兩個1之間的下標之差。 當然也有些複雜的情況,若比較結果為:
101101100101
你是直接翻動中間的兩個“11”處的硬幣再解決其它硬幣呢(因為翻動相鄰的兩個硬幣只算一次操作),還是按上面的規則依次計算呢?
這道題“貪心”之處就在這裡,事實上從左到右依次按上面藍字的規則累加計數,就可求得最優結果。
程式碼:
import java.util.Scanner;
public class FlipCoin {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str1 = input.next();
String str2 = input.next();
char[] arr1 = str1.toCharArray();
char[] arr2 = str2.toCharArray();
int count = 0;
for (int i = 0; i < arr2.length -1; i++) {
if (arr1[i] != arr2[i]) {
arr1[i] = arr2[i];
if (arr1[i+1] =='*') {
arr1[i+1] ='o';
}else {
arr1[i+1] ='*';
}
count++;
}
}
System.out.println(count);
}
}