开灯变形问题(枚举法)
一、問題描述
一排有N盞燈。事先給定每盞燈的初始狀態(開著或關著),你的任務是計算出至少要切換多少盞燈的狀態(把開著的關掉,或把關著的打開),使得這N盞燈交替地打開和關閉。
Input
輸入文件中有多組測試數據,每行一組。首先是一個整數N(1<=N<=10000)表示燈的個數。然后是N個整數,表示這N盞燈的狀態(1表示打開,0表示關閉)。測試數據直到文件尾。
Output
對每組測試數據輸出一個至少需要切換的燈的數目,占一行。
Sample Input
9 1 0 0 1 1 1 0 1 0 3 1 0 1Sample Output
3 0二.問題解析
本題可以采用枚舉法求解:
(1)一共n盞燈,每個燈有2種狀態,則n盞燈共有2^n種狀態,分別是從000……00 到1111……11,可以枚舉2^n種狀態,每種狀態判斷一下是否是開和關交替出現的,如果不是,還要統計一下從初始狀態切換到開關交替狀態需要切換多少盞燈。這種枚舉方法當n很大的時候,顯然花費你很長時間,所以不行。
(2)要使n盞燈開和關交替出現,顯然只有兩種情況:一種要么是所有的奇數序號的燈全部為1且偶數序號的燈也為0,才能顯示出開和關交替狀態;另一種是所有的奇數序號的燈全部為0且偶數序號的燈也為1
才能顯示出開和關交替狀態;所以要分別計算這兩種情況從初始狀態切換到開和關交替狀態分別需要切換多少盞燈。最后取兩種情況下最小切換燈的數量,例如題目中第一個測試用例:
初始狀態:9 1 0 0 1 1 1 0 1 0? ,假設所有的奇數序號全為開著,偶數全為關閉著;則開和關的交替狀態是1 0 1 0 1 0 1 0 1,這種情況需要至少切換的燈的數量為 6;假設所有的奇數序號全為關閉著,偶數全為開著;則開和關的交替狀態是0 1 0 1 0 1 0 1?0?,這種情況需要至少切換的燈的數量為3,所以綜上兩種情況取切換的燈數量最小的為3
(3)從上面可以看出,兩種情況需要切換的燈數量加起來6+3=9,剛好是燈的總數,所以我們只需要求其中一種情況下需要切換的燈的數量num就可以求出其中另一種情況下需要切換的燈的數量n-num,
我們通過判斷當前已求的num是否大于總燈數的一半(即n/2),如果不大于n/2,則直接輸出num,如果大于n/2,則輸出n-num,這種枚舉方法只需求一種情況就行。
三.c語言源碼
#include<stdio.h> #define max 10001 int main(){int a[max];int n,num;while(scanf("%d",&n)!=EOF){num=0;for(int i=1;i<=n;i++){scanf("%d",&a[i]);}//我這里假設奇數序號的全部為1,偶數全為0.這樣才能所有的燈開閉,當然也可以偶數序號的全部為1,奇數全為0,這是兩種情況for(int j=1;j<=n;j++){if(j%2==1&&a[j]==0) num++; //如果發現奇數序號的數為0,則修改,num+1if(j%2==0&&a[j]==1) num++; //如果發現偶數序號的數為1,則修改,num+1}if(num>n/2) printf("%d", n-num); //如果num數目大于一半的數組,則返回另一種情況的修 改的數目n-numelseprintf("%d", num); //如果num數目小于一半的數組,則直接輸出numprintf("\n");}return 0; }?
總結
以上是生活随笔為你收集整理的开灯变形问题(枚举法)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汽车穿越沙漠的算法问题(反推法)
- 下一篇: 感知机的详解