2018級第一次上機《點燈》題解

2021-09-28 14:33:34 字數 1515 閱讀 9383

時間限制:300ms   記憶體限制:65536kb
有n個燈,編號0∼n−10∼n−1,一開始都是關閉狀態。

每次操作會撥動乙個區間[l,r]燈的開關,也就是說,對於燈i,l≤i≤rl≤i≤r,如果i是關閉狀態,則操作會使燈亮,反之會使燈滅。

請問k次操作後有多少燈亮著。

多組輸入資料

每組資料第一行兩個數n,k(1≤n≤109,1≤k≤1051≤n≤109,1≤k≤105)

接下來k行,每行兩個數l,r(0≤l≤r≤n−10≤l≤r≤n−1)

每組資料一行乙個數,表示最後燈亮的個數

輸入樣例

10 1

2 6輸出樣例

5首先,拿到這個題,乙個很直觀的想法就是將n個燈放在乙個陣列裡面並將其置0,然後根據輸入的區間將對應的陣列元素+1,最後用一次遍歷,陣列元素若為偶數,則該燈關閉,陣列元素為奇數,則燈開啟。

但對於這個題,這個思路顯然是不行的。

1.本題最大可能渠道10^9個燈,若用陣列儲存,記憶體會爆掉。

2 本題最大限制時間只有300ms 若以燈為分析物件,即使時間複雜度為o(n),在數量達到10^9的資料下,也會tle。

因此,我們只能以k個輸入的區間為研究物件。

解題思路如下

我們定義乙個結構體陣列,來儲存所給區間的左端點的位置以及右端點的位置+1(假設此時左端點為x,右端點為y,此時被改變狀態的燈是x-y,被改變狀態的燈的數量是y+1-x),並用乙個標籤flag判斷其屬性(flag=0代表為左端點,flag=1代表其為右端點)結構體如下:

typedef struct lpointlight_point;

對於每一次區間的輸入,我們都將其儲存在該結構體陣列之中,由於每個區間有兩個端點,因此結構體陣列應當有2*k個元素。

最後,我們用快速排序將該陣列按從小到大的順序進行排序。

顯然,經過多次開關燈操作之後我們亮燈的區間被分為了很多個小區間,而對於這些小區間,我們可以用上述陣列進行查詢,步驟如下:

首先我們設定乙個臨時變數tmp,用於表示當前燈的狀態。

然後我們對該結構體陣列進行遍歷,對於當前所訪問的店,如果它是l(即flag=0),將tmp+1,如果它是r,將tmp-1;

顯然,當tmp為偶數的時候,代表了兩次開關操作,此時開著的燈就是結構體當前陣列元素(a[i].x)-上乙個陣列元素(a[i-1].x),最後,將所有區間開著的燈的數量加和,就得到了答案;

#include#include#includetypedef struct lpointlight_point;

light_point a[200005];

int cmp(const void *p1,const void *p2)

int main()

qsort(a,2*k,sizeof(light_point),cmp);

for(i=0;i<2*k;i++)

}else

}} printf("%d\n",sum);

} return 0;

}

第一次上機

1 已知a,b均是整型變數,寫出將a,b兩個變數中 的值互換的程式。知識點 變數和運算子綜合 應用 2 給定乙個0 1000的整數,求各位數的和,例 如345的結果是3 4 5 12注 分解數字既可以先 除後模也可以先模後除 知識點 變數和運算子 綜合應用 3 華氏溫度和攝氏溫度互相轉換,從華氏度變...

第一次上機

1 已知a,b均是整型變數,寫出將a,b兩個變數中的值互換的程式。知識點 變數和 運算子綜合應用 package aaaa public class caaas 2給定乙個0 1000的整數,求各位數的和,例 如345的結果是3 4 5 12注 分解數字既可以先 除後模也可以先模後除 知識點 變數和...

C1 2018級演算法第一次上機A題題解

如上所說,將氣泡排序的模擬問題,轉化成歸併排序求逆序對數的問題,而這個問題在之前多次做到,可以稱之為 板子題 了,與歸併排序唯一不同的地方是,多了乙個語句用以記錄逆序對數。cnt len1 lpos 即某步歸併過程中消除的逆序對數等於當左陣列指標 乙個整型型別的下標 所指數大於右陣列指標所指數時,左...