藍橋杯 歷屆試題 翻硬幣(貪心)


歷屆試題 翻硬幣  

時間限制:1.0s   內存限制:256.0MB
問題描述

小明正在玩一個“翻硬幣”的游戲。

桌上放着排成一排的若干硬幣。我們用 * 表示正面,用 o 表示反面(是小寫字母,不是零)。

比如,可能情形是:

**oo***oooo

如果同時翻轉左邊的兩個硬幣,則變為:

oooo***oooo

現在小明的問題是:如果已知了初始狀態和要達到的目標狀態,每次只能同時翻轉相鄰的兩個硬幣,那么對特定的局面,最少要翻動多少次呢?

我們約定:把翻動相鄰的兩個硬幣叫做一步操作,那么要求:

輸入格式

兩行等長的字符串,分別表示初始狀態和要達到的目標狀態。每行的長度<1000

輸出格式

一個整數,表示最小操作步數。

樣例輸入1
**********
o****o****
樣例輸出1
5
樣例輸入2
*o**o***o***
*o***o**o***
樣例輸出2
1

 
  貪心題。
  我的思路是先對兩個字符串進行比較,用數組記錄下比較的結果,0表示字符相同,1表示字符不同。
  用題目給的例子示范:
  **********   o****o****

  比較結果為:

  1000010000

  翻動次數就是兩個1之間的下標之差。

  當然也有些復雜的情況,若比較結果為:
  101101100101

  你是直接翻動中間的兩個“11”處的硬幣再解決其它硬幣呢(因為翻動相鄰的兩個硬幣只算一次操作),還是按上面的規則依次計算呢?

  這道題“貪心”之處就在這里,事實上從左到右依次按上面藍字的規則累加計數,就可求得最優結果。

代碼如下:

 1 #include <iostream>
 2 using namespace std;  3 int main()  4 {  5     char s1[1000];  6     char s2[1000];  7     int cr[1000];    //記錄兩個字符串的比較結果。0為相同,1為不同。 
 8     while(cin>>s1){  9         cin>>s2; 10         int l; 11         for(l=0;s1[l]!='\0';l++);    //計算長度 
12         for(int i=0;i<l;i++){    //比較兩個字符串,並記錄結果 
13             if(s1[i]==s2[i]) 14                 cr[i]=0; 15             else
16                 cr[i]=1; 17  } 18         int f=-1;    //記錄標記位 
19         int _count=0; 20         for(int i=0;i<l;i++){ 21             if(cr[i]==1){    //檢測到一個 1 
22                 if(f==-1){    //如果前面沒有記錄的1的下標,記錄當前1的下標 
23                     f=i; 24  } 25                 else{    //如果前面有一個1了 
26                     _count+=i-f; 27                     f=-1; 28  } 29  } 30  } 31         cout<<_count<<endl; 32  } 33     return 0; 34 }

 

Freecode : www.cnblogs.com/yym2013


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM