藍橋杯小結2 演算法篇(1 3)

2021-10-22 14:51:44 字數 3373 閱讀 5106

區間k大數查詢

問題描述:給定乙個序列,每次詢問序列中第l個數到第r個數中第k大的數是哪個。

這道題目呢,並不難,是演算法裡最簡單的一道了(畢竟是第一道嘛)我只是用了乙個vector就解決了問題,嗯,vector比我們初學時定義的陣列好用得多!

這裡要總結一下vector的一些用法(其實之前也有寫過,我是為了自己多記記,我還沒背會。。。)

定義:vectora;//type為型別,可為int、char、double...

向vector內新增值:他比較好的乙個地方就是不用去關注有幾個元素怎麼樣的,直接vector.pushback(temp);//temp為要追加的值

乙個vector為另乙個vector賦值:這個是我覺得明顯好過於一般的陣列的,他有函式可以直接賦值,不需要使用for迴圈遍歷,很方便,**vector.assign(起始位置,末尾位置),這裡需要注意的是:起始位置就是你要複製過來的第乙個值,而末尾位置是你要的最後乙個值的下乙個,emm,他就是這麼用的,畢竟.end()指向的是vector末尾的結束符,它對應的值是-1,而不是陣列內的值。

排序:排序的函式當然還是sort(a.begin(),a.end());,這裡的end同上,乙個意思

迭代器:vector怎麼說呢,我理解的是它是乙個指向性的,普通陣列可以直接取出值,而它vector需要用*來取值,這時候定義乙個迭代器vector::iterator it;然後用*it來取值。

這個題目很簡單,直接上**好了

#include using namespace std;

int main()

cin>>number;

for(int q=0;q>i;

cin>>j;

cin>>k;

b.assign(a.begin()+i-1,a.begin()+j);

sort(b.begin(),b.end());

it=b.end()-k;

cout<<*it《最大最小公倍數

問題描述:已知乙個正整數n,問從1~n中任選出三個數,他們的最小公倍數最大可以為多少。

這個題目挺有意思,我讀完題之後第一反應覺得在範圍內選三個最大的數,然後就公倍數不就好了嘛,然後像7 8 9,直接乘起來不就是結果嘛(好像太簡單了?這合理嗎?不過我還是試了一試,果然,哈哈,不對。。)

那麼問題出在哪兒了呢?

首先選範圍內的最大的數,思路沒錯,確實是這樣,當然要從大的選,不然結果怎麼最大,然而,直接選最大的三個嘛?誰說他們一定沒公因數的?6 7 8 是不是有了?那觀察一下,7 8 9 和 6 7 8不一樣在哪呢?

7 8 9 奇-偶-奇 6 7 8 偶-奇-偶,我們姑且不看奇數,偶數的話,他們一定是有公因子2的呀,所以必然不對,那如果是偶-奇-偶,要怎麼辦呢?變成奇-偶-奇啊,奇-偶-奇肯定沒有公因子(這兩個奇數中間只隔了乙個數,肯定沒有公因子),好的,那就降乙個偶數變成奇數,那麼降誰呢?如果是降8,那不就和7重了嘛,直接pass,所以只能降6為5,5 7 8這不就成了,但是(又來但是)如果不是6 7 8 ,而是4 5 6呢,偶-奇-偶,降小的偶數,變成3 5 6,這。。3 6 能行嘛,必然不能,那麼觀察,這是為什麼呢?嘿,6 7 8可以是因為8%3!=0,而4 5 6 不可以是因為6%3==0,(為什麼非是3呢,因為這是降得最多的情況了,再降又出來偶數了,不是白瞎了嘛),那來看4 5 6 ,不能降4為3 不能降6為5 那怎麼辦?去掉3的倍數嘛,我們直接把6降為3 變成3 4 5不就好了嘛(這確實是最大的)

這道題倒是沒有用什麼vector、map什麼的,關鍵是思路,然後就很簡單了,那,上**

#include using namespace std;

int main()

{ long long n;

cin>>n;

/*兩個數互質時,他們的最小公倍數為二者的乘積

兩個數相鄰時,這兩個數互質

當n為奇數時:

很顯然 n*(n-1)*(n-2) 即為所求

當n為偶數時:

n(n-1)(n-2)中n和n-2一定有公因子2,不可取,所以將其中乙個降為奇數

分析知,降大數得到的乘積更大 但就降為了(n-1) 不可取 所以降小數為(n-3)

這時即為n(n-1)(n-3) 此時,若n%3==0 (n-3)%3==0 不可取 所以降n為(n-1)

*/if(n%2!=0)//n為奇數

cout << n*(n-1)*(n-2)問題描述:如果乙個自然數n的k進製表示中任意的相鄰的兩位都不是相鄰的數字,那麼我們就說這個數是k好數。求l位k進製數中k好數的數目。例如k = 4,l = 2的時候,所有k好數為11、13、20、22、30、31、33 共7個。由於這個數目很大,請你輸出它對1000000007取模後的值。

這個是動態規劃,哇,動態規劃真的好難啊,我是個fw。

好吧,fw也是要繼續進步的

這也就是在這個k進製表示的數中,要保證相鄰的兩位不能是自然數中相鄰的,也是這兒我更明了了動態規劃和貪心的區別,要是這道題用貪心的話,我可能只能得到乙個結果,因為他是貪心的選擇當前最優,而動態規劃可以把所有從全域性考慮合理的都求出來(啊,我不知道我對不對,反正我這麼想了)

還是看題吧:l控制有幾位數,k控制每位數可以取得值有哪些,那麼l控制外層迴圈咯,k控制內層,這個我倒是開始就想到了,但是我沒想到的是內層怎麼寫呢?(我想著也是好多人的問題),這個的關鍵在於拆分,雖然有l層,但我們只要保證每兩層中的下一層不和上一層相鄰,那最終不就好了嘛,動態規劃還有個點就是乙個要找初始狀態,就是不需要迴圈就知道的東西,在這道題中就是,當l==1時,只有一層,那麼他要求的個數就是k,(只有一位還能有什麼相不相鄰的),那我們記錄下這個初始,這個dp陣列怎麼定義也是難點:l等於1了,那這個肯定要用,放在陣列第一維,那二維到底放什麼呢?不是有k個嘛,我們總要知道這k個都是誰吧,所以二維放當前位的值,那dp=?,值放什麼呢?自然就是個數了,例如l=2,k=4,dp[1][0]=1;dp[1][1]=1;dp[1][2]=1;dp[1][3]=1;

這樣的話,他的含義就是:dp[i][j]為當有i位時,以j結尾的可行的個數

那我們下一位中,以j結尾的可行個數就是上一位裡所有不挨著j的值的個數的和(emmm,拗口,可能真的只把我自己講明白了吧)

還是看**吧(反正我理清了)

#include using namespace std;

int main()

{ int k,l;

__int64 dp[105][105];

cin>>k>>l;

memset(dp,0,sizeof(dp));//少了這句話,兩個樣例過不了

//l位k進製

//l==1

for(int i=0;i好了,今天的總結結束了,謝謝大家(哈哈哈,我就是個戲精)

藍橋杯習題 2(基礎訓練1 3)

問題描述 給定乙個年份,判斷這一年是不是閏年。當以下情況之一滿足時,這一年是閏年 1.年份是4的倍數而不是100的倍數 2.年份是400的倍數。其他的年份都不是閏年。輸入格式 輸入包含乙個整數y,表示當前的年份。輸出格式 輸出一行,如果給定的年份是閏年,則輸出yes,否則輸出no。include i...

2014藍橋杯 1 3題

1.啤酒飲料啤酒每罐2.3元,飲料每罐1.9元。小明買了若干啤酒和飲料,一共花了82.3元。我們還知道他買的啤酒比飲料的數量少,請你計算他買了幾罐啤酒。注意 答案是乙個整數。請通過瀏覽器提交答案。不要書寫任何多餘的內容 例如 寫了飲料的數量,新增說明文字等 思路分析 簡單列舉 include int...

藍橋杯題目練習 提公升篇 藍橋杯 2n皇后問題

給定乙個n n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行 同一列或同一條對角線上 任意的兩個白皇后都不在同一行 同一列或同一條對角線上。問總共有多少種放法?n小於等於8。輸入輸入的第一行為乙個整數n,表示棋盤的大小。接下來n行,每行n...