acm週末學習總結

2021-09-20 21:47:04 字數 3693 閱讀 3956

如果不進行大量的練習,只是被動的聽課,那樣一點效果都沒有。acm很看投入,投入少想見成果,很難。更何況我們的演算法課才12周。

這兩天看了看搜尋的一些題目,我算是剛剛接觸搜尋,我覺得難度挺大,看透了一些題目之後就好很多了,那一陣學搜尋的時候沒理解。

本週還是主要對單調佇列和二分進行學習,二分還好,固定模板,固定思路,就是題目型別靈活多變,上午做的一道題我一直以為用貪心,沒去試,用的二分,過了,有空去用貪心試試。二分法挺靈活的。

poj2823

【題意】

移動區間(長度固定)最值問題。 【分析】

這類思想在單調佇列優化思想中尤其重要:區間長度為k,求區間內的最大值,考慮第i個數和第j個數,j-i=要入隊資料a[i],刪除隊尾元素;當隊頭<=i-k時,刪除隊頭元素。

單調佇列: 加入找最小數,考慮順序a,b(b在a的後面),若b#include #include using namespace std;

const int n = 1100000;

int n,k;

int a[n];

int dandiao_que[n]; //單調遞減佇列(最大),單調遞增佇列(最小)

int head,tail;

//遞增

void min()

for(i = k-1; i < n; i++)

}//遞減

void max()

for(i = k-1; i < n; i++)

}int main()

poj-3250-bad hair day 題意:有 n

頭牛頭朝東站成一列。每頭牛有一定的高度,並且只能看到它右邊比他矮的牛的牛頭,直到被某頭高度大於等於它的高度的牛所擋住。計算每頭牛能看到的牛頭頂的數量之和

sample input

6 10 3 7 4 12 2 sample output

#include #include #include #define maxn 80050

#define ll long long

using namespace std;

ll q[maxn];

int main()

cout<#include const int m = 100001<<1;

int sum[m],q[m];

int main()

for(int i=2;i< n+k;i++)

sum[i] += sum[i-1];

head = rear = 0;

q[head] = 0;

max = int_min;

for(int i=1;i< n+k;i++) //列舉每個區間終點

}end = end>n ? end%n : end;

printf("%d %d %d\n",max,start,end);

}return 0;

}

hdu 4193 單調佇列

將乙個序列形成乙個環,序列中的每個數字輪流作為起始端,問有多少個起點,可以使前1項,前兩項……前n項加和全都為非負數。

既然陣列是迴圈的,自然想到先複製一遍,然後求sum[i],列舉每乙個長度為n的區間,看最小值是否滿足即可。

#include #define n 2000002

int a[n],sum[n],que[n];

int main()

int nn = n << 1;

for(i = 1; i <= nn; ++i)

sum[i] = sum[i-1] + a[i];

int head = 0,tail = 0;

int res = 0;

for(i = 1; i < nn; ++i)

printf("%d\n",res);

}return 0;

}

hdu3474

題意: 有一環形項鍊,項鍊上有兩種珍珠分別用c,j來表示.現在問是否存在這樣的切割點,滿足以下條件:

沿著該切割後的項鍊的一端依次取出珍珠,但手裡的c珍珠數必須時刻不少於手裡的j珍珠數.問這樣的切割點有幾個.

由n(10^6)個資料組成的圓環,資料為1和-1,問從乙個點開始順時針或逆時針,能遍歷完所有點,並且保證中間過程中sum>=0。

分析:首先暴力o(n^2)是不可行的。

假設從i點開始,這裡僅考慮向左,必須保證sum(j,i)>=0, i-n =0,即sum[i] - max(sum[j])>=0.

要求區間[i-n,i-1]最大值,維護單調遞減佇列即可。

#include#include#includeusing namespace std;

#define n 1000005

int t,sum[2*n],lab[2*n];

char le[2*n];

bool vis[2][2*n];

int front,rear;

void solve(int n,int d)

for(i=n;i<=2*n;i++)

}int main()

return 0;

}

廣告印刷 【問題描述】

最近,afy決定給toj印刷廣告,廣告牌是刷在城市的建築物上的,城市裡有緊靠著的n(n<=400000)個建築。afy決定在上面找一塊盡可能大的矩形放置廣告牌。我們假設每個建築物都有乙個高度,從左到右給出每個建築物的高度h1,h2…hn,0【分析】考慮構造乙個單調非遞減佇列,從左至右,依次加入到佇列中,肯定會有元素出佇列,設當前要插入的數為a,要出佇列的數為b,必有b>=a,則b向右能到達的最遠距離就是b-a。注意在求解時,讓0先入佇列,這樣保證每個資料都會出佇列。同理,左極限也可求出。

#include #define maxn 1000000

int h[maxn+5]; //建築物的高度

int n; //建築物的數目

int mq[maxn+5]; //單調佇列,對內元素為建築物高度的下標

int left[maxn+5]; //left[i]:在第i個建築物左側,不比它的高度小的建築物數量

int right[maxn+5]; //right[i]:在第i個建築物右側,不比它的高度小的建築物數量

void calcleft()

left[i] = i - mq[rear-1] - 1;

mq[rear++] = i; }}

void calcright()

right[i] = mq[rear-1] - i - 1;

mq[rear++] = i; }}

int maxrectarea()

} return maxarea;

}int main()

h[0] = h[n+1] = -1;

calcleft();

calcright();

for (i = 1; i <= n; i++)

cout << endl;

for (i = 1; i <= n; i++)

cout << endl;

cout << maxrectarea() << endl;

} return 0;

}

acm週末學習總結

搜尋是萬能演算法 如何找所有解?列舉。列舉的方法?遞迴。遞迴的組合?搜尋。廣搜while not queue.empty begin 可加結束條件 tmp queue.top 從tmp迴圈拓展下乙個狀態next if 狀態next合法 then begin 生成新狀態next next.step t...

acm週末學習總結

這週做了洛谷上面的題目,還是發現很多自己的不足,最大的問題是思路不清晰。細節不到位。最近幾周把精力集中在acm上,要為進入校隊而努力了!然後今天和乙個舍友組了個隊打了一場比賽,最後就是有5道題有思路卻只ac了3道,並查集的題目我們都不會,用別的方法沒做出來,暴力不是總會出奇蹟。細節,還是得注意細節。...

週末學習總結

關於下午的網路賽,我們的水平是3題,但是只出了2題。最後5分鐘打表找了e的規律,我們還天真的以為找到了規律。殊不知我們找的規律已經超過了題目所給的範圍。一開始隊友手快用stl的deque寫完交,超時,我玄學優化交後發現記憶體超限。關於stl,要學習的還有很多很多,我們覺得用起來很方便,全都封裝好了,...