1. 程式人生 > >翻硬幣 (藍橋杯)

翻硬幣 (藍橋杯)

上題

時間限制: 1 Sec 記憶體限制: 128 MB
提交: 29 解決: 18
[提交][狀態][討論版]

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

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

比如,可能情形是:**oo***oooo

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

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

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

輸入 每個測試點(輸入檔案)存在多組測試資料。

每個測試點的第一行為一個整數Task,表示測試資料的組數。

在一組測試資料中:

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

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

樣例輸入
2
··················· 謹以 · 代表本應出現的10個 ‘*’
o****o****
o**o***o**
o***o**o** 樣例輸出 5 1

分析

最初想到的是BFS暴力列舉但是時間顯然不夠

之後優化了一下只翻找周邊有不一樣的硬幣

如例一 直翻找第一個 和第五個

可以A了但是仍不是最優 可以說差了很遠
·
·
·
·

正確答案是將目標狀態和起始狀態用1 0 表示 相同為0 不同為1;

下面表示轉化:如例二

初始值為

··················· 謹以 · 代表本應出現的10個 ‘*’

目標值為

o****o****

將以上內容相同的用0 表示 不同的用1 表示

結果為

1000010000

然後我們所要做的就是統計1之間的相隔的位數

上文顯然是 5
·
·
·
·
·

·
·

當然還有複雜的 例如

1001011101010

當有多個1 0 怎麼辦 ?

這裡我們有多種選擇抵消的方法
1. 相鄰的1相互抵消
2. 從左端依次抵消
3. 從右端一次抵消

事實證明2. 3 相同

這就回歸到了貪心演算法上

證明可得2, 3 法最優 證明過程不詳

所以上文的過程為 1 4 抵消 + 5 6 抵消 + 6 8 抵消 + 10 12 抵消
·
·
·
·

如果1個個數有奇數個呢?

孩子放棄吧 那是無解的 (考慮只有第一個不同的情況)

上程式碼

#include <iostream>
#include <cstdio>
using namespace std;

int main(){
    int T;
    scanf("%d", &T);
    while (T--){
        char s1[1000];
        char s2[1000];
        int cr[1000];    //記錄兩個字串的比較結果。0為相同,1為不同。
        cin >> s1;
        cin >> s2;
        int l;
        for (l = 0; s1[l] != '\0'; l++);    //計算長度
        for (int i = 0; i<l; i++){    //比較兩個字串,並記錄結果
            if (s1[i] == s2[i])
                cr[i] = 0;
            else
                cr[i] = 1;
        }
        int f = -1;    //記錄標記位
        int _count = 0;
        for (int i = 0; i<l; i++){
            if (cr[i] == 1){    //檢測到一個 1
                if (f == -1){    //如果前面沒有記錄的1的下標,記錄當前1的下標
                    f = i;
                }
                else{    //如果前面有一個1了
                    _count += i - f;
                    f = -1;
                }
            }
        }
        cout << _count << endl;
    }
    return 0;
}

相關推薦

硬幣 藍橋

上題 時間限制: 1 Sec 記憶體限制: 128 MB 提交: 29 解決: 18 [提交][狀態][討論版] 題目描述 小明正在玩一個“翻硬幣”的遊戲。 桌上放著排成一排的若干硬幣。我們用 * 表示正面,用 o 表

歷屆試題 硬幣 藍橋

小明正在玩一個“翻硬幣”的遊戲。桌上放著排成一排的若干硬幣。我們用 * 表示正面,用 o 表示反面(是小寫字母,不是零)。比如,可能情形是:**oo***oooo如果同時翻轉左邊的兩個硬幣,則變為:oooo***oooo現在小明的問題是:如果已知了初始狀態和要達到的目標狀態,每次只能同時翻轉相鄰的兩個硬幣,那

初級演算法——最大公約數與最小公倍數藍橋

思路:這裡使用的是輾轉相除法求最大公約數,而  最小公倍數 = 兩數相乘/最大公約數   #include<stdio.h> int main(){ int m,n,a,b,c; printf("input two numbers:"); scanf("%d%d",&a

藍橋斐波那契數列快速求解

問題描述: Fibonacci數列的遞推公式為:Fn=Fn-1+Fn-2,其中F1=F2=1。 當n比較大時,Fn也非常大,現在我們想知道,Fn除以10007的餘數是多少。 資料規模: 1 <= n <= 1,000,000 輸入輸出樣例: 輸入格式: 10 輸出格式: 55 C/C

藍橋歷屆試題 合根植物

問題描述  w星球的一個種植園,被分成 m * n 個小格子(東西方向m行,南北方向n列)。每個格子裡種了一株合根植物。  這種植物有個特點,它的根可能會沿著南北或東西方向伸展,從而與另一個格子的植物合成為一體。  如果我們告訴你哪些小格子間出現了連根現象,你能說出這個園中一

藍橋基礎練習 2n皇后問題

我們先學習下經典案例中的八皇后問題接著學習2n皇后問題問題描述  給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條對角線上,任意的兩個白皇后都不在同一行、同一列或同一條對角線上。問總共有

01字串藍橋

ostream color main col text cout div esp 輸出 問題描述 對於長度為5位的一個01串,每一位都可能是0或1,一共有32種可能。它們的前幾個是: 00000 00001 00010 00011 00100 請按從小到大的順序輸出這32

字母圖形藍橋

nbsp 規律 出了 color 輸入格式 abcd 解答 問題 ++ 問題描述 利用字母可以組成一些美麗的圖形,下面給出了一個例子: ABCDEFG BABCDEF CBABCDE DCBABCD EDCBABC 這是一個5行7列的圖形,請找出這個圖形的規律,並輸出一個

矩陣硬幣 數學 藍橋

    小明先把硬幣擺成了一個 n 行 m列的矩陣。隨後,小明對每一個硬幣分別進行一次 Q 操作。對第x行第y列的硬幣進行 Q 操作的定義:將所有第 i*x 行,第 j*y列的硬幣進行翻轉。其中i和j為任意使操作可行的正整數,行號和列號都是從1開始。    當小明對所有硬幣都進行了一次 Q操作後,他發現了一個

連號區間數藍橋

連號區間數 小明這些天一直在思考這樣一個奇怪而有趣的問題:在1~N的某個全排列中有多少個連號區間呢?這裡所說的連號區間的定義是:如果區間[L, R] 裡的所有元素(即此排列的第L個到第R個元素)遞增排序後能得到一個長度為R-L+1的“連續”數列,則稱這個區間連號區間。當N很

藍橋2018JAVA B組 日誌分析

順序輸出 輸入 lis ont 輸出格式 system i++ iterator 一個 日誌統計 小明維護著一個程序員論壇。現在他收集了一份"點贊"日誌,日誌共有N行。其中每一行的格式是: ts id 表示在ts時刻編號id的帖子收到一個"贊"。 現在小明想統計有哪

藍橋 矩陣硬幣打表+二分

網上其他人的答案好像都是用數學方法解決的。做這道題的時候一看就感覺是找規律的題,所以先打個表。因為後面要用到大數處理,所以是Java語言打表程式碼(就是按題目意思暴力):import java.io.FileNotFoundException; import java.io.

藍橋:矩陣硬幣大數開根號

  對於10%的資料,n、m <= 10^3;  對於20%的資料,n、m <= 10^7;  對於40%的資料,n、m <= 10^15;  對於10%的資料,n、m <= 10^1000(10的1000次方)。 我的思路:他是問翻之前有多少個硬幣是反面朝上的,所以這個反面朝上的

藍橋 歷屆試題 硬幣貪心

小明正在玩一個“翻硬幣”的遊戲。 桌上放著排成一排的若干硬幣。我們用 * 表示正面,用 o 表示反面(是小寫字母,不是零)。 比如,可能情形是:**oo***oooo 如果同時翻轉左邊的兩個硬幣,則變為:oooo***oooo 現在小明的問題是:如果已知了初始狀態和要達到的目標狀態,每次只能同時翻

藍橋 歷屆試題 硬幣Java

小明正在玩一個“翻硬幣”的遊戲。 桌上放著排成一排的若干硬幣。我們用 * 表示正面,用 o 表示反面(是小寫字母,不是零)。 比如,可能情形是:**oo***oooo 如果同時翻轉左邊的兩個硬幣,則變為:oooo***oooo 現在小明的問題是:如果已知了初始狀態和要達到的目標狀態,每次只能同時翻

全排列來自藍橋

做了道藍橋杯的題,發現並不會做,不過這個題做了也算漲了個知識點。題目:相信大家都知道什麼是全排列,但是今天的全排列比你想象中的難一點。我們要找的是全排列中,排列結果互不相同的個數。比如:aab 的全排列就只有三種,那就是aab,baa,aba。程式碼框中的程式碼是一種實現,請

程式設計競賽基礎課藍橋省賽[目錄]

計蒜客練習題,堅持每天練習 快速提升程式碼能力: 起始日期:2019-1-12 題號 題目 完成情況 1 a+b問題 自己完成 2

矩陣硬幣C++

問題描述   小明先把硬幣擺成了一個 n 行 m 列的矩陣。   隨後,小明對每一個硬幣分別進行一次 Q 操作。   對第x行第y列的硬幣進行 Q 操作的定義:將所有第 i*x 行,第 j*y 列的硬幣進行翻轉。   其中i和j為任意使操作可行的正整數,

演算法訓練 比較字串 藍橋C++

先上程式碼吧! #include<iostream> #include<algorithm> #include<string> #include<cstring> #include<queue>

動態規劃之K好數藍橋ALGO-3

import java.util.Scanner; public class Demo01 { private int[][] matrix(int k, int l){ int[][] m