牛客網真題練習-ios
雙核處理編程
一種雙核CPU的兩個核可以同時的處理任務,如今有n個已知數據量的任務須要交給CPU處理,假設已知CPU的每一個核1秒能夠處理1kb,每一個核同時只能處理一項任務。n個任務能夠按照任意順序放入CPU進行處理,如今須要設計一個方案讓CPU處理完這批任務所需的時間最少,求這個最小的時間。 服務器
輸入包括兩行: 第一行爲整數n(1 ≤ n ≤ 50) 第二行爲n個整數length[i](1024 ≤ length[i] ≤ 4194304),表示每一個任務的長度爲length[i]kb,每一個數均爲1024的倍數。
輸出一個整數,表示最少須要處理的時間
5 3072 3072 7168 3072 1024
9216
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int MAXN = 55; const int MAXM = 800000; int n,sum, num[MAXN], dp[MAXM]; int main(){ freopen("in.txt", "r", stdin); int tmp, ans; scanf("%d", &n); sum = 0; for(int i=0; i<n; ++i){ scanf("%d", &num[i]); sum += num[i]; } memset(dp, 0, sizeof(dp)); dp[0] = 1; for(int i=0; i<n; ++i){ tmp = num[i]/1024; for(int j=sum/1024; j>=tmp; --j){ if(dp[j - tmp] == 1){ dp[j] = 1; } } } ans = 0; tmp = sum/(2*1024); for(int i=0; i<sum/1024; ++i){ if(dp[tmp-i] == 1){ ans = 1024*(tmp-i); break; } if(dp[tmp+i] == 1){ ans = 1024*(tmp+i); break; } } ans = max(sum-ans, ans); printf("%d\n", ans ); return 0; }
趕去公司app
終於到週末啦!小易走在市區的街道上準備找朋友聚會,忽然服務器發來警報,小易須要當即回公司修復這個緊急bug。假設市區是一個無限大的區域,每條街道假設座標是(X,Y),小易當前在(0,0)街道,辦公室在(gx,gy)街道上。小易周圍有多個出租車打車點,小易趕去辦公室有兩種選擇,一種就是走路去公司,另一種就是走到一個出租車打車點,而後從打車點的位置坐出租車去公司。每次移動到相鄰的街道(橫向或者縱向)走路將會花費walkTime時間,打車將花費taxiTime時間。小易須要儘快趕到公司去,如今小易想知道他最快須要花費多少時間去公司。 學習
輸入數據包括五行:
第一行爲周圍出租車打車點的個數n(1 ≤ n ≤ 50)
第二行爲每一個出租車打車點的橫座標tX[i] (-10000 ≤ tX[i] ≤ 10000)
第三行爲每一個出租車打車點的縱座標tY[i] (-10000 ≤ tY[i] ≤ 10000)
第四行爲辦公室座標gx,gy(-10000 ≤ gx,gy ≤ 10000),以空格分隔
第五行爲走路時間walkTime(1 ≤ walkTime ≤ 1000)和taxiTime(1 ≤ taxiTime ≤ 1000),以空格分隔
輸出一個整數表示,小易最快能趕到辦公室的時間
2 -2 -2 0 -2 -4 -2 15 3
42
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> using namespace std; const int MAXN = 50; int X[MAXN], Y[MAXN]; int main(){ freopen("in.txt", "r", stdin); int ans, gx, gy, Wt, Tt, n, tmp; scanf("%d", &n); for(int i=0; i<n; ++i){ scanf("%d", &X[i]); } for(int i=0; i<n; ++i){ scanf("%d", &Y[i]); } scanf("%d%d", &gx, &gy); scanf("%d%d", &Wt, &Tt); ans = (abs(gx) + abs(gy))*Wt; for(int i=0; i<n; ++i){ tmp = (abs(X[i]) + abs(Y[i]))*Wt + (abs(gx - X[i]) + abs(gy - Y[i]))*Tt; if(tmp < ans){ ans = tmp; } } printf("%d\n", ans ); return 0; }
消除重複元素ui
小易有一個長度爲n序列,小易想移除掉裏面的重複元素,可是小易想是對於每種元素保留最後出現的那個。小易遇到了困難,但願你來幫助他。 spa
輸入包括兩行: 第一行爲序列長度n(1 ≤ n ≤ 50) 第二行爲n個數sequence[i](1 ≤ sequence[i] ≤ 1000),以空格分隔
輸出消除重複元素以後的序列,以空格分隔,行末無空格
9 100 100 100 99 99 99 100 100 100
99 100
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <map> #include <vector> using namespace std; const int MAXN = 55; int main(){ freopen("in.txt", "r", stdin); int n, num[MAXN]; scanf("%d", &n); for(int i=0; i<n; ++i){ scanf("%d", &num[i]); } vector<int> ans; map<int, int> mp; for(int i=n-1; i>=0; --i){ if( mp.find( num[i] ) == mp.end()){ mp[ num[i] ] = 1; ans.push_back( num[i] ); } } for(int i=ans.size()-1;i>=0; --i){ if(i==0){ printf("%d\n", ans[i] ); }else{ printf("%d ", ans[i] ); } } return 0; }
工做安排設計
如今有n位工程師和6項工做(編號爲0至5),如今給出每一個人可以勝任的工做序號表(用一個字符串表示,好比:045,表示某位工程師可以勝任0號,4號,5號工做)。如今須要進行工做安排,每位工程師只能被安排到本身可以勝任的工做當中去,兩位工程師不能安排到同一項工做當中去。若是兩種工做安排中有一我的被安排在的工做序號不同就被視爲不一樣的工做安排,如今須要計算出有多少種不一樣工做安排計劃。 blog
輸入數據有n+1行: 第一行爲工程師人數n(1 ≤ n ≤ 6) 接下來的n行,每行一個字符串表示第i(1 ≤ i ≤ n)我的可以勝任的工做(字符串不必定等長的)
輸出一個整數,表示有多少種不一樣的工做安排方案
6 012345 012345 012345 012345 012345 012345
720
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> using namespace std; const int MAXN = 10; int n, ans, var[MAXN][MAXN], vis[MAXN]; void dfs(int cur){ if(cur == n){ ans++; return; } for(int i=0; i<=5; ++i){ if(vis[i] == 0 && var[cur][i] == 1){ vis[i] = 1; dfs(cur+1); vis[i] = 0; } } } int main(){ freopen("in.txt", "r", stdin); char st[MAXN]; scanf("%d", &n); memset(var, 0, sizeof(var)); for(int i=0; i<n; ++i){ scanf("%s", st); for(int j=0; j<strlen(st); ++j){ var[i][st[j]-'0'] = 1; } } ans = 0; memset(vis, 0, sizeof(vis)); dfs(0); printf("%d\n", ans ); return 0; }
奇怪的表達式求值遊戲
常規的表達式求值,咱們都會根據計算的優先級來計算。好比*/的優先級就高於+-。可是小易所生活的世界的表達式規則很簡單,從左往右依次計算便可,並且小易所在的世界沒有除法,意味着表達式中沒有/,只有(+, - 和 *)。如今給出一個表達式,須要你幫忙計算出小易所在的世界這個表達式的值爲多少
輸入爲一行字符串,即一個表達式。其中運算符只有-,+,*。參與計算的數字只有0~9. 保證表達式都是合法的,排列規則如樣例所示。
輸出一個數,即表達式的值
3+5*7
56
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int MAXN = 100; int main(){ char st[MAXN]; int flag, ans, tmp, len, i; while(scanf("%s", st) != EOF){ ans = 0; len = strlen(st); tmp = 0; i = 0; flag = 1; while(i < len){ if(st[i] == '+'){ flag = 1; }else if(st[i] == '-'){ flag = 2; }else if(st[i] == '*'){ flag = 3; }else{ tmp = st[i] - '0'; while(i < len && st[i+1]>='0' && st[i+1]<='9'){ i++; tmp = tmp*10 + st[i]-'0'; } if(flag==1){ ans += tmp; }else if(flag==2){ ans -= tmp; }else{ ans *= tmp; } } i++; } printf("%d", ans); } return 0; }
塗棋盤
小易有一塊n*n的棋盤,棋盤的每個格子都爲黑色或者白色,小易如今要用他喜歡的紅色去塗畫棋盤。小易會找出棋盤中某一列中擁有相同顏色的最大的區域去塗畫,幫助小易算算他會塗畫多少個棋格。
輸入數據包括n+1行:
第一行爲一個整數n(1 ≤ n ≤ 50),即棋盤的大小
接下來的n行每行一個字符串表示第i行棋盤的顏色,'W'表示白色,'B'表示黑色
輸出小易會塗畫的區域大小
3 BWW BBB BWB
3
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> using namespace std; const int MAXN = 55; int n, ans, tmp, mp[MAXN][MAXN]; void dfs(int cx, int cy, int label){ tmp++; mp[cx][cy] = 0; if(cx+1<n && mp[cx+1][cy] == label){ dfs(cx+1, cy, label); } } int main(){ char ch; scanf("%d", &n); for(int i=0; i<n; ++i){ getchar(); for(int j=0; j<n; ++j){ scanf("%c", &ch); if(ch == 'B'){ mp[i][j] = -1; }else{ mp[i][j] = 1; } } } ans = 0; for(int i=0; i<n; ++i){ for(int j=0; j<n; ++j){ if(mp[i][j] != 0){ tmp = 0; dfs(i, j, mp[i][j]); if(tmp > ans){ ans = tmp; } } } } printf("%d", ans); return 0; }
集合
小易最近在數學課上學習到了集合的概念,集合有三個特徵:1.肯定性 2.互異性 3.無序性.
小易的老師給了小易這樣一個集合:
S = { p/q | w ≤ p ≤ x, y ≤ q ≤ z }
須要根據給定的w,x,y,z,求出集合中一共有多少個元素。小易才學習了集合還解決不了這個複雜的問題,須要你來幫助他。
輸入包括一行: 一共4個整數分別是w(1 ≤ w ≤ x),x(1 ≤ x ≤ 100),y(1 ≤ y ≤ z),z(1 ≤ z ≤ 100).以空格分隔
輸出集合中元素的個數
1 10 1 1
10
#include <iostream> #include <algorithm> #include <set> using namespace std; int GCD(int x, int y){ if(x == 0){ return y; } return GCD(y%x, x); } int main(){ int w, x, y, z, tv; cin >> w >> x >> y >> z; set< pair<int,int> > st; for(int i=w; i<=x; ++i){ for(int j=y; j<=z; ++j){ tv = GCD(min(i,j), max(i,j)); st.insert( make_pair(i/tv, j/tv) ); } } cout << st.size() << endl; return 0; }
小易記單詞
小易參與了一個記單詞的小遊戲。遊戲開始系統提供了m個不一樣的單詞,小易記憶一段時間以後須要在紙上寫出他記住的單詞。小易一共寫出了n個他能記住的單詞,若是小易寫出的單詞是在系統提供的,將得到這個單詞長度的平方的分數。注意小易寫出的單詞可能重複,可是對於每一個正確的單詞只能計分一次。
輸入數據包括三行:
第一行爲兩個整數n(1 ≤ n ≤ 50)和m(1 ≤ m ≤ 50)。以空格分隔
第二行爲n個字符串,表示小易能記住的單詞,以空格分隔,每一個單詞的長度小於等於50。
第三行爲m個字符串,系統提供的單詞,以空格分隔,每一個單詞的長度小於等於50。
輸出一個整數表示小易能得到的分數
3 4 apple orange strawberry strawberry orange grapefruit watermelon
136
#include <iostream> #include <string> #include <map> using namespace std; int main(){ int n, m, ans = 0; string st; cin >> n >> m; map<string, int> mp; for(int i=0; i<n; ++i){ cin >> st; mp[st] = 1; } for(int i=0; i<m; ++i){ cin >> st; if(mp.find(st) == mp.end()){ continue; }else{ if(mp[st] == 1){ ans += st.length() * st.length(); mp[st] = 2; } } } cout << ans << endl; return 0; }
調整隊形
在幼兒園有n個小朋友排列爲一個隊伍,從左到右一個挨着一個編號爲(0~n-1)。其中有一些是男生,有一些是女生,男生用'B'表示,女生用'G'表示。小朋友們都很頑皮,當一個男生挨着的是女生的時候就會發生矛盾。做爲幼兒園的老師,你須要讓男生挨着女生或者女生挨着男生的狀況最少。你只能在原隊形上進行調整,每次調整隻能讓相鄰的兩個小朋友交換位置,如今須要儘快完成隊伍調整,你須要計算出最少須要調整多少次可讓上述狀況最少。例如:
GGBBG -> GGBGB -> GGGBB
這樣就使以前的兩處男女相鄰變爲一處相鄰,須要調整隊形2次
輸入數據包括一個長度爲n且只包含G和B的字符串.n不超過50.
輸出一個整數,表示最少須要的調整隊伍的次數
GGBBG
2
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> const int MAXN = 100; int main(){ int len, bb, gg, lb, rb, ans; char ch[MAXN]; while(scanf("%s", ch) != EOF){ len = strlen(ch); bb = 0; gg = 0; lb = 0; rb = 0; for(int i=0; i<len; ++i){ if(ch[i] == 'B'){ lb += i - bb; bb++; }else{ rb += i - gg; gg++; } } ans = lb>rb?rb:lb; printf("%d\n", ans ); } return 0; }