問你從1到2021出現了多少個數字6python
簽到題,莽暴力就完遼ios
print(602)
小明同窗正在學習一種新的語言。在該語言中,若是出現了一次wa或者一次aw,則表明出現了一個警告。若是出現了連續的wa或者連續的aw,則表明出現了一個錯誤。小明因爲學習比較粗心,因此他想要知道本身剛剛寫完的做業中一共出現了多少處警告和錯誤。下面是小明剛剛寫完的做業,請你幫助小明找到他一共出現了多少次警告和多少次錯誤。算法
abcwaawawawa中出現了一次警告(wa)和一次錯誤(awawaw)數組
abcdefg中沒有出現一次警告和錯誤
waawwaawwawa中出現了四次警告(兩次wa和兩次aw)和一次錯誤(wawa)
awawwawa中只出現了兩次錯誤(awaw和wawa)函數
沒好好讀題而錯失五分,嗯,下次必定要好好讀題(╥﹏╥)學習
用一個「指針」從頭掃一遍,若是連續兩個是wa,就判斷後兩個是否是也是wa,若是是就讓wa的答案加一,而後跳到下一個不是wa的地方;若是不是wa,就讓aw加一,指針移動2優化
對於另外一種aw的狀況同上ui
#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <queue> #include <stdlib.h> #include <sstream> #include <map> #include <set> using namespace std; #define inf 0x3f3f3f3f #define MAX 5000 + 50 #define endl '\n' //#define mod 1000000007 //const int mod = 1e9 + 7; #define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0) #define mem(a,b) memset((a),(b),sizeof(a)) typedef long long ll ; //不開longlong見祖宗! inline int IntRead(){char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0';ch = getchar();}return s * w;} string s; int main(){ cin>>s; int wa = 0, aw = 0; for(int i = 0; i < s.size() && i != -1;){ if(s[i] == 'w' && s[i + 1] == 'a'){ if(s[i + 2] == 'w' && s[i + 3] == 'a'){ ++wa; i += 4; while (s[i] == 'w' && s[i + 1 ] == 'a') { i += 2; } } else { ++aw; i += 2; } } else if(s[i] == 'a' && s[i + 1] == 'w'){ if(s[i + 2] == 'a' && s[i + 3] == 'w'){ ++wa; i += 4; while (s[i] == 'a' && s[i + 1] == 'w') { i += 2; } } else { ++aw; i += 2; } } else ++i; } cout<<aw<<endl<<wa<<endl; return 0; } /* iawaswapwauawhawdwafwanbiopwanivgbikvblvbwawawawvolyuvgbololvolgbyolgyowagbolgawgboplwawaolgyolwaogblwaygbowawagwabwayawopwawagyowabwaowapjwapcfrtuywawacvujwawawaufttyfuftywawawatifgugbgbyguwawawawayugbigwwwytigwygwgbwyoawawgoghwaogwborgrewabouyhwabyuhowabhnwawauygbawyawuwaoawfcawaaaahwaywauwagwawefwaafmbawklawjiawihnwanhawawawawijwajiofjeriofgjrefjhwaewarwaowagwahwauwaiwarwaiwaqwarwahwaqwawwaowapfweofbwewafwahwaiwaewawwawawawawafwawawawaeiufwepfhnewfwahwajwatwafowawajtokshwawafwaiwahwafwahmgoewawawawafkfjkewnwawafiewhfwawawafjkernhawkrenwawawawafujnrheiowanwakawawawawwanoifewajrwaoawawfweojnwawawawawawawafjkwenawawferkwmpwawawawaforeijawawferhfiueorghwuwafguwegfwaghrwiufgwahweofgowaidwiweaiwwawieyiwe */
小明最近癡迷於斐波那契數列(1,1,2,3,5……),可是最近他又有了新的奇思妙想,就是對於斐波那契數列的相鄰的兩個數相乘取倒數而後將每一項進行相加,因爲小明只喜歡思考不喜歡動手,因此如今他想讓你幫他算下這樣一個新的數列的前13項的和爲多少?(結果用分數表示,且保留最簡分數)spa
通分以後獲得pwa
而後就能夠直接用循環莽他o(≧v≦)o
記得最後寫個gcd求最大公約數來進行分式約分
#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <queue> #include <stdlib.h> #include <sstream> #include <map> #include <set> using namespace std; #define inf 0x3f3f3f3f #define MAX 1000 + 50 #define endl '\n' //#define mod 1000000007 //const int mod = 1e9 + 7; #define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0) #define mem(a,b) memset((a),(b),sizeof(a)) typedef long long ll ; //不開longlong見祖宗! inline int IntRead(){char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0';ch = getchar();}return s * w;} ll ans = 1; ll gcd(ll a, ll b){ if(b)return gcd(b, a % b); else return a; } int main(){ // cout<<"6535086616739/3684083162760\n"; int tr[100]; tr[1] = 1;tr[2] = 1; for(int i = 3; i <= 15; ++i){ tr[i] = tr[i - 1] + tr[i - 2]; } for(int i = 1; i <= 14; ++i)ans *= tr[i]; // cout<<ans<<endl; ll sum = 0; for(int i = 2; i <= 14; ++i){ sum += ans / (tr[i] * tr[i - 1]); } cout<<ans<<endl; cout<<sum<<endl; cout<<sum / gcd(sum, ans)<<'/'<<ans / gcd(sum, ans)<<endl; return 0; }
小明同窗最近喜歡上了排列組合,可是如今有這樣的一道題把他難住了,已知有一組數字(2,5,3,6,3,6,7,3,7,8)共10個,對於這組數字進行排列後,能夠將排列好的數字分爲三個部分,且三個部分都是分別有序的(升序或逆序),小明想知道可以有知足條件的多少種排列方式?
當時一直在想這個題有什麼規律,正着來逆着來都想過,可是感受不太行。
結果誰知道這題就是個大暴力??
對全部的全排列去枚舉兩個分割點,判斷是否符合題意
此次還學到了一個函數:
is_sorted(tr + l,tr + r, cmp)
判斷 tr 數組的 l 到 r 的區間是否按照cmp函數的方法進行的排序,忽律cmp時,就默認從小到大
#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <queue> #include <stdlib.h> #include <sstream> #include <map> #include <set> using namespace std; #define inf 0x3f3f3f3f #define MAX 5000 + 50 #define endl '\n' //#define mod 1000000007 //const int mod = 1e9 + 7; #define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0) #define mem(a,b) memset((a),(b),sizeof(a)) typedef long long ll ; //不開longlong見祖宗! inline int IntRead(){char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0';ch = getchar();}return s * w;} bool cmp(int x, int y){ return x > y; } int tr[] = {2, 3, 3, 3, 5, 6, 6, 7, 7, 8}; int main(){ int ans = 0; do{ bool judge = 0; for(int i = 0; i <= 7; ++i){ for(int j = i + 1; j <= 8; ++j){ if((is_sorted(tr, tr + 1 + i) || is_sorted(tr, tr + i + 1, cmp)) &&(is_sorted(tr + 1 + i, tr + 1 + j) || is_sorted(tr + 1 + i, tr + 1 + j, cmp)) && (is_sorted(tr + 1 + j, tr + 10) || is_sorted(tr + 1 + j, tr + 10, cmp))){ judge = 1; break; } } if(judge)break; } if(judge)++ans; }while (next_permutation(tr, tr + 10)); cout<<ans<<endl; return 0; }
坤坤給你一個邊長爲n的等邊三角形圖形,請你查出圖形內等邊三角形的個數。 由於數據過大,因此要求答案對1e9+7取模。
每多一行,就會貢獻出一些正三角形和倒三角形,因此只須要記錄每一行貢獻的三角形的數量便可
觀察得:每一行貢獻的正三角形的數量爲(n + 1) * n / 2
而逆三角形貢獻的數量也是有規律滴:
公差爲-2的等差數列
第 i 行的通項公式爲
經過求和公式
因此得第 i 行的逆三角形數量的求和公式
由觀察得:
因此
第 i 行貢獻的逆三角的數量爲:
綜上所述:
第i行貢獻第三角形的數量爲:
#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <queue> #include <stdlib.h> #include <sstream> #include <map> #include <set> using namespace std; #define inf 0x3f3f3f3f #define MAX 5000 + 50 #define endl '\n' //#define mod 1000000007 const int mod = 1e9 + 7; #define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0) #define mem(a,b) memset((a),(b),sizeof(a)) typedef long long ll ; //不開longlong見祖宗! inline int IntRead(){char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0';ch = getchar();}return s * w;} ll n, m; int main(){ n = 20210411; ll sum = 0; for(ll i = 1; i <= n; ++i){ m = i / 2; ll a = ((i + 1) * i / 2) % mod; ll b = ((i - m) * m) % mod; sum += (a + b + mod) % mod; sum %= mod; } cout<<sum<<endl; return 0; }
記得開longlong,否則就算你公式推對了,也是必wa,耶穌都救不了你
又是努力刷題的一天。衆所周知wyk是國一大佬喜歡幫羣友解答問題。
如今xmy好奇羣裏的聊天記錄有多少條是@wyk的,可是他在忙着摸魚。
因此找到了你,給了你N條聊天記錄,讓你幫他算一下。
注意:保證聊天記錄的字母都是在ASSIC內。聊天記錄存在空格,也可能以空格開頭或結尾。@wyk必須連續才能生效,一條聊天記錄保證在一行。
簽到題,無限find便可
須要注意的是,輸入字符串以前getchar一下,否則你會發現死活輸不進去最後一個字符串(///▽///)
#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <queue> #include <stdlib.h> #include <sstream> #include <map> #include <set> using namespace std; #define inf 0x3f3f3f3f #define MAX 1000 + 50 #define endl '\n' //#define mod 1000000007 //const int mod = 1e9 + 7; #define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0) #define mem(a,b) memset((a),(b),sizeof(a)) typedef long long ll ; //不開longlong見祖宗! inline int IntRead(){char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0';ch = getchar();}return s * w;} string s, ss; int main(){ int t; cin>>t; getchar(); int ans = 0; ss = "@wyk"; while (t--) { getline(cin,s); if(s.find(ss) != -1){ ++ans; } } cout<<ans<<endl; return 0; } /* 10 abcbdaasddwj@wyk dasdsafav@Alan acdbbd@alan@wyk @zbrnb ??CC?? abababab wgyyds @wykyyds @wyk 111 endcccc@wyk */
這一天你來到了藍橋杯的考場,你發現考場是一個N*M的矩陣。
由於你的羣友不少,你知道考場內每一個人有多強,而且把實力換算成了數值。(由於有的人太弱了,因此可能出現實力值是負數的可能)
你想知道考場內實力總和最大的矩陣****區域的實力和是多少。
(注意:區域是按照矩形劃分的)
比賽的時候我是打暴力,就是枚舉x1,y1,x2,y2,並採用二維前綴和進行了優化,獲得了百分之四十的分,時間複雜度是$$O(n2m2)$$
而正解的方法是枚舉行的位置,而後再經過對行進行相似於連續的最大子串的dp來優化時間複雜度,時間複雜度是$$O(n^2m)$$
先對每列求其前綴和,而後第一層for循環循環的是上行的位置,第二層for循環循環的是下行的位置,而後再一層for循環就進行類dp操做
此時能拿百分之七十的分
剩下的三十分,是這個題的數據範圍比較噁心,n*m<=2e5,就有多是n = 1,m = 2e5,就沒辦法開二維數組,否則會爆!一樣的,多是n = 2e5 , m = 1,此時就時間複雜度又過不去了,因此,咱們對n > m 的狀況再次進行優化,把矩陣轉置一下,並交換n和m,再進行上述的操做
#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <queue> #include <stdlib.h> #include <sstream> #include <map> #include <set> using namespace std; #define inf 0x3f3f3f3f #define MAX 5000 + 50 #define endl '\n' //#define mod 1000000007 //const int mod = 1e9 + 7; #define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0) #define mem(a,b) memset((a),(b),sizeof(a)) typedef long long ll ; //不開longlong見祖宗! inline int IntRead(){char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0';ch = getchar();}return s * w;} int n, m; int main(){ io; cin>>n>>m; if(n > m){//要進行矩陣轉置 vector<vector<int>>a(n + 1, vector<int>(m + 1)); vector<vector<int>>sum(m + 1, vector<int>(n + 1)); for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j)cin>>a[i][j]; vector<vector<int>>tr(m + 1, vector<int>(n + 1)); for(int i = 1; i <= m; ++i)for(int j = 1; j <= n; ++j)tr[i][j] = a[j][i]; swap(n, m); for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j)sum[i][j] = sum[i - 1][j] + tr[i][j];//對每一列都求前綴和 ll ans = -inf; for(int i = 1; i <= n; ++i){ for(int j = i; j <= n; ++j){ ll cnt = 0; for(int k = 1; k <= m; ++k){ //這裏的0ll至關於一個爲值爲0的變量,若是cnt小於0,就說明前面選的連續的幾個大和已經小於0了,是負數,無論本身是否是負數,本身加上一個負數確定是比原來小,因此加了這個負數還不如不加,就加0,這裏就很相似於求連續的最大子串dp cnt = max(cnt, 0ll) + sum[j][k] - sum[i - 1][k]; ans = max(ans, cnt);//實時跟新答案 } } } cout<<ans<<endl; } else{//同上,只不過沒有轉置操做了 vector<vector<int>>tr(n + 1, vector<int>(m + 1)); vector<vector<int>>sum(n + 1, vector<int>(m + 1)); for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j)cin>>tr[i][j]; for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j)sum[i][j] = sum[i - 1][j] + tr[i][j]; ll ans = -inf; for(int i = 1; i <= n; ++i){ for(int j = i; j <= n; ++j){ ll cnt = 0; for(int k = 1; k <= m; ++k){ cnt = max(cnt, 0ll) + sum[j][k] - sum[i - 1][k]; ans = max(ans, cnt); } } } cout<<ans<<endl; } return 0; }
小航是計算機系的學生,但他並不喜歡本身的專業。在課餘時間,小航喜歡研究社會學的內容,在他通過了多年的研究後,他發現了一個偉大的定理:世界上任意兩我的之間最少須要k個友誼紐帶就能夠所有鏈接。他須要向世界公佈這個研究成果,可是他尚未對這個定理進行驗證,因爲他急着陪女友,因此將驗證這個定理的任務交給了他的朋友小杰和小坤。
因爲人數太多,而致使任務量很是大,因此小杰和小坤找到了你,請你幫助他們驗證這個結論。
又是一個會錯題意的題(╥﹏╥),比賽的時候覺得是找到一個最短的路,使得全部的點連在一塊兒,那麼我就直接用並查集判掉,若是存在的話就至關於一顆最小生成樹,輸出n-1便可
可是!題意是:任意兩我的之間都有路能到,並求出最遠的兩我的之間的路有多長
也就是多源最長路?
我用的是n次迪傑斯特拉,每次都判斷有沒有點到不了,而後更新最大值
#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <queue> #include <stdlib.h> #include <sstream> #include <map> #include <set> using namespace std; #define inf 0x3f3f3f3f #define MAX 5000 + 50 #define endl '\n' //#define mod 1000000007 //const int mod = 1e9 + 7; #define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0) #define mem(a,b) memset((a),(b),sizeof(a)) typedef long long ll ; //不開longlong見祖宗! inline int IntRead(){char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0';ch = getchar();}return s * w;} int n, m, a, b, tot; int dist[MAX]; int head[MAX]; bool vis[MAX]; int ans; struct ran{ int to, next, val; inline bool operator < (const ran &x)const{ return val > x.val; } }tr[MAX]; priority_queue<ran>q; ran now, nextt; void built(int u, int v){ tr[++tot].to = v; tr[tot].next = head[u]; tr[tot].val = 1; head[u] = tot; } int dijkstra(int s){ mem(dist, inf); mem(vis, 0); dist[s] = 0; // vis[s] = 1; now.to = s; now.val = 0; q.push(now); while (!q.empty()) { now = q.top();q.pop(); if(vis[now.to])continue; vis[now.to] = 1; for(int i = head[now.to]; i != -1; i = tr[i].next){ int u = tr[i].to; if(dist[u] > tr[i].val + dist[now.to]){ dist[u] = tr[i].val + dist[now.to]; nextt.to = u; nextt.val = dist[u]; q.push(nextt); } } } ans = 0; for(int i = 1; i <= n; ++i){ ans = max(ans, dist[i]); } if(ans == inf ) return -1; else return ans; } int main(){ io; cin>>n>>m; mem(head, -1); mem(tr, 0); int maxn = 0; for(int i = 1; i <= m; ++i){ cin>>a>>b; built(a, b); built(b, a); } for(int i = 1; i <= n; ++i){ int k = dijkstra(i); if(k == -1){ cout<<-1<<endl; return 0; } else { maxn = max(maxn, k); } } cout<<maxn<<endl; return 0; }
公元2200年科學家發明了點對點傳送門,隨後基建狂魔發揮了優良傳統,在城市之間進行了大規模建設。
如今你接到了一個任務,上級給你發了一份資料,這份資料是XX地區的傳送門建設規劃資料,共M條。
領導要求你完成這些任務,使得這個地區的N座城市能夠互相傳送,你比較喜歡摸魚,因而你想知道完成任務的最短期。若是沒法完成任務,則輸出-1。
注意:A市與B市能夠利用C市中轉,能夠算互相傳送。只要達到N座城市能夠互相傳送的目的就能夠,因此規劃資料不必定所有建設。
最小生成樹的板子題
用Kruskal算法按照權值從小到大排序,獲得一顆生成樹時,此時的權值是完成全部任務的時間最小值。
#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <queue> #include <stdlib.h> #include <sstream> #include <map> #include <set> using namespace std; #define inf 0x3f3f3f3f #define MAX 100000 + 50 #define endl '\n' //#define mod 1000000007 //const int mod = 1e9 + 7; #define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0) #define mem(a,b) memset((a),(b),sizeof(a)) typedef long long ll ; //不開longlong見祖宗! inline int IntRead(){char ch = getchar();int s = 0, w = 1;while(ch < '0' || ch > '9'){if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0';ch = getchar();}return s * w;} int n, m, a, b, c, ans, cnt; int fa[MAX]; struct ran{ int x, y, val; }tr[MAX]; bool cmp(ran a, ran b){ return a.val < b.val; } void init(){ cnt = 0; mem(tr, 0); ans = 0; for(int i = 1; i <= n; ++i)fa[i] = i; } int findd(int x){ return x == fa[x] ? x : fa[x] = findd(fa[x]); } void emerge(int x, int y){ fa[findd(x)] = findd(y); } int main(){ io; cin>>n>>m; init(); for(int i = 1; i <= m; ++i){ cin>>tr[i].x>>tr[i].y>>tr[i].val; } sort(tr + 1, tr + 1 + m, cmp); for(int i = 1; i <= m; ++i){ if(findd(tr[i].x) != findd(tr[i].y)){ // ans += tr[i].val; ++cnt; emerge(tr[i].x, tr[i].y); if(cnt == n - 1){ cout<<tr[i].val<<endl; return 0; } } } cout<<-1<<endl; return 0; }
真不愧是暴力杯(bushi