1. 程式人生 > >貪心演算法-翻硬幣

貪心演算法-翻硬幣

問題描述
小明正在玩一個“翻硬幣”的遊戲。

桌上放著排成一排的若干硬幣。我們用 * 表示正面,用 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); } }