@今天的c語言你學廢了嗎?!!----開燈問題(20210202
阿新 • • 發佈:2021-02-06
@今天又學廢了呢----開燈問題(C語言)
2021-02-02
讀完題目,我最直接的解題方法是:
將開著的燈等價為1,關著的燈等價為0
這樣一來,將n個燈編到一個數組裡陣列長度是n+1,並初始化為零(有人或許會困惑他的長度,但為了在for迴圈遍歷時可以遍歷到n這個編號,需要這樣,而且第零個的值始終為零,也就是說它可以忽視)
來到關鍵的地方,我用了兩個for來實現每個人(1~k)來按開關都可以經過每個開關(1~n),開關燈我用了if語句:關著的燈從0變成1,開著的燈從1變成0。
最後,當第k個人按下某個燈的開關時,我再次使用了if語句對開著燈進行判斷並輸出其編號。
#include <stdio.h>
int main()
{
int n,k;
scanf("%d %d",&n,&k);
int a[n+1] = {0};
for(int i = 1;i <= k;i ++){
for(int j = 1;j <= n;j ++){
if(j % i == 0){
if(a[j] == 0) a[j] = 1;
else if (a[j] == 1) a[j] = 0;
}
if(i == k) if(a[j] == 1) printf("%d " ,j);
}
}
return 0;
}```
巢狀的for迴圈語句使該程式的時間複雜度up up up
所以小five他叫勁腦汁
甚至薅禿了頭,想到了另一種可能簡單點的演算法(實際並沒有):
Ps:這裡定義0為開燈
#include <stdio.h>
int main()
{
int n,k;
scanf("%d %d",&n,&k);
int a[n+1] = {0}; //0為開燈
for(int i = 2;i <= k;i ++){
for(int j = i;j <= n;j += i){
if (a[j] == 0) a[j] = 1;
else if (a[j] == 1) a[j] = 0;
}
}
for(int l = 1;l <= n;l ++){
if(a[l] == 0) printf("%d ",l);
}
return 0;
}
總結一下吧:
細節很重要! 陣列的長度為n+1!
略雞肋的兩種方法! 掉光頭髮是關鍵!
一不小心學到的東西?memset(a,0,sizeof(a)初始化陣列用,但據說只能初始“0”,“-1”和字串。【哦吼,還得加標頭檔案】