翻硬幣 (藍橋杯)
上題
時間限制: 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