南海云课堂春季11(T)K1 拓展:单调队列
問題A 幸運數
Description
我們將一個正整數分解成若干個質因數(質數因子)的乘積,若得到的質因數的個數也為質數,則稱這個整數為幸運數。例如 12 = 2 × 2 × 3,它有 3 個質因數,分別是 2、2、3,而 3 也是質數,所以 12 是一個幸運數;210 不是一個幸運數,因為 210 = 2 × 3 × 5 × 7,它有 4 個質因數,分別是 2、3、5、7,而 4 不是質數。
現在,請你編程求:不大于 n 的所有幸運數。
Format
Input
輸入一行一個整數 n。
Output
若干行,每行一個幸運數。要求按照從小到大的順序輸出。
Samples
Sample Input 1
12Sample Output 1
4 6 8 9 10 12Limitation
對于 50% 的數據,n ≤ 1000;
對于 80% 的數據,n ≤ 10000;
對于 100% 的數據,2 ≤ n ≤ 100000。
#include<bits/stdc++.h> using namespace std; const int maxx=1e5+15; long long n,a[100005],b; int main() {a[0]=1;a[1]=1;for(register int i=2;i<=sqrt(maxx);++i){for(register int j=i+i;j<=maxx;j+=i){a[j]=1;}}cin>>n;for(register int i=4;i<=n;++i){if(a[i]==1){int num=i,num2=0;for(int j=2;num!=1;){if(num%j==0) num/=j,num2++;else{while(num%j!=0) j++;}}if(a[num2]==0) cout<<i<<endl;}}return 0; }問題B?字符串展開
Description
對于一個字符串,如果其中含有類似于“d - h”或者“4 - 8”的字符子串,我們就把它當作一種簡寫。還原輸出此字符串時,用連續遞增的字母或數字串替代其中的減號。上面兩個子串分別輸出為“defgh” 和 “45678”。具體約定如下:
(1)遇到下面的情況需要對字符串進行展開:在輸入的字符串中,出現了減號 “-”,減號兩側同為小寫字母或同為數字,且按照 ASCII 碼的順序,減號右邊的字符嚴格大于左邊的字符。
(2)如果減號右邊的字符恰好是左邊字符的后繼,只刪除中間的減號,例如:“d - e” 應輸出為 “de”,“3 - 4”應輸出為 “34”。如果減號右邊的字符按照 ASCII碼的順序小于或等于左邊字符,輸出時,要保留中間的減號,例如:“d - d” 應輸出為 “d - d”,“3 - 1” 應輸出為“3 - 1”。
現在,輸入一個字符串,請將此字符串展開輸出。
Format
Input
輸入一行一個字符串,長度不超過 200,僅由數字、小寫字母和減號 “-” 組成。行首和行末均無多余空格。
Output
輸出一行一個字符串,為展開后的字符串。
Samples
Sample Input 1
abcs-w-y1234-9s-4zzSample Output 1
abcstuvwxy123456789s-4zz?
#include<bits/stdc++.h> using namespace std; string s; int main() {cin>>s;for(int i=0;i<s.size();i++){if(s[i]!='-'){cout<<s[i];}if(s[i]=='-'){if(s[i-1]>='a'&&s[i-1]<='z'&&s[i+1]>='a'&&s[i+1]<='z'&&int(s[i-1])<int(s[i+1])){for(int j=int(s[i-1])+1;j<int(s[i+1]);j++){cout<<char(j);}}else if(s[i-1]>='A'&&s[i-1]<='Z'&&s[i+1]>='A'&&s[i+1]<='Z'&&int(s[i-1])<int(s[i+1])){for(int j=int(s[i-1])+1;j<int(s[i+1]);j++){cout<<char(j);}}else if(s[i-1]>='0'&&s[i-1]<='9'&&s[i+1]>='0'&&s[i+1]<='9'&&int(s[i-1])<int(s[i+1])){for(int j=int(s[i-1])+1;j<int(s[i+1]);j++){cout<<char(j);}}else cout<<"-";}}return 0; }問題C?懶羊羊吃草
Description
眾所周知,懶羊羊是所有小羊里最貪吃的一只。然而,鮮為人知的是,懶羊羊也有存儲糧食的習慣。而更讓大家吃驚的事實是,我們的懶羊羊做事很有條理,每當他存儲一份糧食時,他會專門拿出一個筐來存放。因此,他的倉庫里有很多很多筐的青草。而我們的懶羊羊又是一個經常饞嘴的小羊,每當他想吃草時,就會從倉庫里找出數量最少的一筐草,把它吃掉。可是懶羊羊因為草吃得太多了導致大腦運轉緩慢,所以他不得不向你請求支援,幫他找出他應該吃數量為多少的青草。
Format
Input
第 1 行有 1 個正整數 n,表示懶羊羊一共進行了 n 次操作。
第 2 行至第 n+1 行,每行表示一個懶羊羊的操作:當這行形式為單獨一個字符 “q” 時,表示懶羊羊肚子餓了,要吃掉倉庫里當前數量最少的那份青草;當這行形式為一個字符 “i” 和一個整數 k 時,表示懶羊羊將一份數量為 k 的青草存入了倉庫,“i” 和 k 之間用 1 個空格隔開。
保證每次詢問時,倉庫里都有草可吃,且所有操作中懶羊羊至少會吃一次草。
Output
輸出若干行。每當輸入為 “q” 時,輸出一行一個數,表示懶羊羊當前吃掉的那份青草的數量是多少。
Samples
Sample Input 1
5 i 5 i 2 q i 9 qSample Output 1
2 5Explanation
樣例一說明:
共有 5 次操作,分別為懶羊羊存入數量為 5 的青草,存入數量為 2 的青草,吃掉當前數量最少的青草(2),存入數量為 9 的青草,吃掉當前數量最少的青草(5)。
Limitation
對于 30% 的數據,1 ≤ n ≤ 3000;
對于 60% 的數據,1 ≤ n ≤ 40000;
對于 100% 的數據,1 ≤ n ≤ 1000000,1 ≤ k ≤ 2147483647。
#include<bits/stdc++.h> using namespace std; int n; char c; priority_queue<int,vector<int>,greater<int> > b; int main() {scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%s",&c);if(c=='i'){int k;scanf("%d",&k);b.push(k);}else{printf("%d\n",b.top());b.pop();}}return 0; }問題D 方格稿紙
Description
小 y 終于在小學學會了一些字、詞、句子,會寫一點作文了。某一天,小 y買了一張方格稿紙來寫作文,稿紙是 n 行 m 列的,形狀如下所示(圖中 n = m = 5):
?
某天小 y 的鄰居小小 x 來小 y 家玩,無聊地用黑墨水筆把小 y 新買的方格稿紙涂黑了很多格子。每個格子不是完全黑色就是完全白色,如下圖所示。
?
小 y 不能責怪小 x。作文寫不成了,他也覺得很無聊,就開始數里面有多少“魔幻方陣”。如果稿紙中一個 k × k 的正方形區域滿足以下兩個條件,那么它就是魔幻方陣:
(1)黑白格子的數量差不能超過 1;
(2)k 不能小于 2。
上圖染色后的方格稿紙共有 9 個魔幻方陣(6 個 2 × 2 的魔幻方陣,3 個 3 × 3 的魔幻方陣)。
現在,請你幫助小 y 編程計算被染色的稿紙里面有多少個魔幻方陣。
Format
Input
第一行有 2 個正整數 n 和 m(之間以一個空格分隔),表示 n 行 m 列的稿紙。
接下來 n 行,每行有 m 個 0 或 1 的整數(之間以一個空格分隔),代表這一行中每一個格子的顏色。如果這個數是 1 則為黑色,是 0 則為白色。
Output
輸出一行一個整數,表示稿紙中魔幻方陣的個數。
Samples
Sample Input 1
5 5 1 0 1 1 1 1 0 1 0 1 1 1 0 1 1 1 0 0 1 1 1 1 1 1 1Sample Output 1
9Limitation
對于 50% 的數據,1 ≤ n ≤ 10,1 ≤ m ≤ 10;
對于 75% 的數據,1 ≤ n ≤ 180,1 ≤ m ≤ 180;
對于 100% 的數據,1 ≤ n ≤ 300,1 ≤ m ≤ 300。
#include<bits/stdc++.h> using namespace std; int n,m,a[305][305],b[305][305],sum=0; int main() {cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>a[i][j];b[i][j]=b[i-1][j]+b[i][j-1]-b[i-1][j-1]+a[i][j];}}int black=0,white=0;for(int k=2;k<=n;k++){black=0;white=0;for (int i=1;i<=n-k+1;i++){for (int j=1;j<=m-k+1;j++){int x=i+k-1;int y=j+k-1;black=b[x][y]-b[i-1][y]-b[x][j-1]+b[i-1][j-1];white=k*k-black;if(abs(black-white)<=1) sum++;}}}cout<<sum;return 0; }問題E?二項式展開
Description
JSOI2017 夏令營后,小 y 就在學習林老師的《數學一本通》。在《組合數學》那一章發現這樣一個問題,在整式的乘法中,有:(a + b)^1(a+b)1?= a + b ,(a + b)^2(a+b)2?=?a^2a2?+ 2ab +?b^2b2,...等等,這些都可以用簡單的手算求得。但是他想如果要求?(a + b)^n(a+b)n?的展開式,就不容易很快手算了。
現在,他需要你和他一起編程解決這個問題。
Format
Input
輸入一行一個整數 n。
Output
輸出一行一個完整的表達式。
格式為:(a + b)^n(a+b)n?=??a^n?an?+??a^(n-1)?a(n?1)b +??a^(n-2)?a(n?2)b^2b2?+ ... +??b^n?bn
其中:“?” 為系數,如果系數為 1,則需要省略系數;如果次數為 1,則需要省略次數;如果次數為 0,則需要省略;如果系數為 0,則需要省略這一項。
注意:前面?(a + b)^n(a+b)n?的次數是必有的,表達式的任何地方都不能有多余空格。
Samples
Sample Input 1
5Sample Output 1
(a+b)^5=a^5+5a^4b+10a^3b^2+10a^2b^3+5ab^4+b^5Limitation
對于 30% 的數據,n ≤ 18;
對于 60% 的數據,n ≤ 34;
對于 100% 的數據,1 ≤ n ≤ 67。
#include<bits/stdc++.h> using namespace std; unsigned long long n,atou,btou,jia,a[70][70]; int main() {cin>>n;if(n==1){cout<<"(a+b)^1=a+b";return 0;}atou=n-1;btou=1;a[1][1]=1;a[1][2]=1;jia=2;for(int i=1;i<=n;i++){for(int j=1;j<=jia;j++){if(j==1) a[i][1]=1;else if(j==jia) a[i][jia]=1;else{a[i][j]=a[i-1][j]+a[i-1][j-1];}}jia++;}cout<<"(a+b)^"<<n<<"=";for(int i=1;i<=n+1;i++){if(i==1) cout<<"a^"<<n<<"+";else if(i==n+1) cout<<"b^"<<n;else{cout<<a[n][i]<<"a";if(atou==1) cout<<"b^"<<btou<<"+";else if(btou==1) cout<<"^"<<atou<<"b"<<"+";else cout<<"^"<<atou<<"b"<<"^"<<btou<<"+";atou--;btou++;}}return 0; } /* (a+b)^5=a^5+5a^4b+10a^3b^2+10a^2b^3+5ab^4+b^5 1 1 1 2 1 1 3 3 1 1 4 6 4 1 */問題F 布丁
Description
Farmer John建立了一個布丁工廠。在接下來的 N(1 ≤ N ≤ 40000)個星期里,原料牛奶和勞動力的價格會有很大波動。Farmer John希望能夠在滿足消費者需求的前提下盡量減小花費。
Farmer John預計接下來每個星期會需要 Ci(1 ≤ Ci ≤ 5000)元錢來生產一單位布丁,且消費者會需要 Pi(0 ≤ Pi ≤ 10000)單位布丁。
Farmer John每星期即可以生產布丁,也可以儲存布丁供以后使用。它的倉庫存儲一星期一單位布丁需要 S(1 ≤ S ≤ 100)元錢。但是由于布丁有保質期,所以最多只能保存 T(0 ≤ T ≤ 40000)星期。也就是說 x 星期生產的布丁可以在(x + T)星期銷售,但是不能在(x + T + 1)星期銷售。
請幫助Farmer John安排生產與存儲的方案使得在滿足消費者需求的前提下盡量減小花費。
Format
Input
第一行為 N,S 與 T。
第二行到第 N + 1 行:每一行兩個數,即 Ci 與 Pi。
Output
僅一個數,即滿足顧客需求前提下的最小花費。
Samples
Sample Input 1
5 10 3 12 1 21 2 27 4 45 5 52 3Sample Output 1
488Limitation
對于 50% 的數據,滿足 1 ≤ N ≤ 5000,1 ≤ T ≤ 5000;
對于 100% 的數據,見題目描述。
#include<bits/stdc++.h> using namespace std; long long n,s,tim,ans=0,a[40005],b[40005],q[40005],h=1,t=0; int main() {cin>>n>>s>>tim;for(int i=1;i<=n;i++){ cin>>a[i]>>b[i];} for(int i=1;i<=n;i++){while(h<=t&&q[h]<=i-tim) h++;while(h<=t&&a[q[t]]+s*(i-q[t])>a[i]) t--;q[++t]=i;ans+=(a[q[h]]+s*(i-q[h]))*b[i];}cout<<ans;return 0; }問題G 滑動窗口(單調隊列)
Description
給你一個長度為N的數組,一個長為K的滑動的窗體從最左移至最右端,你只能見到窗口的K個數,每次窗體向右移動一位,如下表:
你的任務是找出窗口在各位置時的 max value 以及 min value。
Format
Input
第一行,兩個整數 n 和 k;
第二行為長度為 n 的數組。
Output
兩行:
第一行每個位置的 min value;
第二行每個位置的 max value。
Samples
Sample Input 1
8 3 1 3 -1 -3 5 3 6 7Sample Output 1
-1 -3 -3 -3 3 3 3 3 5 5 6 7Limitation
對于 20% 的數據,n ≤ 500;
對于 50% 的數據,n ≤ 100000;
對于 100% 的數據,n ≤ 1000000。
#include<bits/stdc++.h> using namespace std; long long n,k,a[1000005]; deque<int> q,s; int main() {cin>>n>>k;for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=n;i++){while(!s.empty()&&s.front()<=i-k) s.pop_front();while(!s.empty()&&a[s.back()]>=a[i]) s.pop_back();s.push_back(i);if(i>=k) cout<<a[s.front()]<<" ";}cout<<endl;for(int i=1;i<=n;i++){while(!q.empty()&&q.front()<=i-k) q.pop_front();while(!q.empty()&&a[q.back()]<=a[i]) q.pop_back();q.push_back(i);if(i>=k) cout<<a[q.front()]<<" ";}return 0; }總結
以上是生活随笔為你收集整理的南海云课堂春季11(T)K1 拓展:单调队列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kubernetes CKA题库(附答案
- 下一篇: “换个江湖再见”阿里巴巴20周年年会直击