Test on 11/10/2018
杭電半日遊,這新生賽出的題目比較簡單,剛開始四十分鐘寫了三道題,並拿了一個一血,得到氣球超開心。
可是後來就寫不出來了,還是學的太少。
感覺還是有增長信心的,雖然感覺自己以前學過欺負他們,但是我也忘完了呀。
還是要努力啊QAQ
不要喪失希望,永遠保持鬥志,加油吧。
A:熱烈的決鬥者
Description
Jeff正在玩一種卡牌遊戲,在這個遊戲中,每個回合玩家可以執行以下兩種操作無數次:
1.使用一張手上的牌。
2.命令場上的一隻生物對敵方造成傷害,每一隻生物在一個回合內最多攻擊一次。
現在Jeff的場上擁有n只生物,第i只怪物擁有ai點攻擊力與bi點血量。
同時,Jeff手上有m張手牌。由於他的運氣實在太差了,他的所有手牌都只有一個功能——使場上一隻生物的攻擊力等於它的血量。
現在正是斬殺對手的關鍵回合,Jeff希望他能通過一種合理的策略,對敵方造成最高的傷害。請幫助Jeff計算他能造成的最高傷害。
Input
題目包含多組測試資料。
第一行是一個整數T,表示有T組測試資料。
對於每組測試資料,第一行包含兩個整數n,m(0 <= n,m <= 500),表示場上生物數量和手牌數量。
接下來的n行,每行包含兩個整數ai,bi(1 <= ai,bi <= 10000000),表示第i只怪物的攻擊力和血量。
Output
輸出Jeff在一個回合內能對敵方造成的最高傷害。Examples
Input
1 3 2 1 3 2 4 5 3Output
正確解法:
原本就是全部加a[i],把b[i]-a[i] 排序,取出前m個在加起來,不知道為什麼wa
等待正解。
B:qw的表白
Description
qw喜歡上了一個美麗的女孩,並勇敢向她表白。但女神喜歡演算法厲害的男生,便給他出了一道題:
給定包含n
單身二十年的qw非常想談戀愛,你能幫幫他嗎?
Input
多組資料。
第一行給出資料組數T(1≤T≤50 )
每組資料首先給定兩個整數n ,m ,表示數列中數的個數和詢問個數。(1≤n,m≤50000 )
隨後一行給出n 個整數 a1,a2,a3...an (1≤ai≤1e9 )
隨後m 行,每行兩個整數 L , R ,表示當前詢問的數值範圍區間。(1≤L≤R≤1e9 )
Output
對於每個詢問,單獨輸出一行,包含一個整數,表示數列中滿足條件的數個數Examples
Input
1 5 3 1 2 3 4 5 1 4 4 9 1 25Output
2 2 5正確解法:
我以為1e9 long long 會超,其實不會,那麼就很簡單
long long 排序,二分搜尋。
寫了半天二分搜尋,後面發現可能有一個二分函式,有點sad,但無論學了什麼都要保證自己會呀。
1 #include "pch.h" 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<string> 6 #include<cstring> 7 #include<algorithm> 8 using namespace std; 9 int n, m; 10 long long a[50100],l,r; 11 long long upp(int n,long long r) 12 { 13 int ll = 0, rr = n+1; 14 while (ll+1 < rr) 15 { 16 int mid = (ll + rr) / 2; 17 if (a[mid] <= r) ll = mid; 18 else rr = mid; 19 } 20 return rr; 21 } 22 long long downn(int n, long long l) 23 { 24 int ll = 0, rr = n; 25 while (ll + 1 < rr) 26 { 27 int mid = (ll + rr) / 2; 28 if (a[mid] >= l) rr = mid; 29 else ll = mid; 30 } 31 return ll; 32 } 33 int main() 34 { 35 int t; 36 cin >> t; 37 while (t--) 38 { 39 cin >> n >> m; 40 memset(a, 0, sizeof(a)); 41 for (int i = 1; i <= n; i++) 42 { 43 cin >> a[i]; 44 a[i] = a[i] * a[i]; 45 } 46 sort(a + 1, a + n + 1); 47 for (int i = 1; i <= m; i++) 48 { 49 cin >> l >> r; 50 cout << upp(n, r) - downn(n, l) - 1 << endl; 51 } 52 } 53 return 0; 54 }View Code
1 #include "pch.h" 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<string> 6 #include<cstring> 7 #include<algorithm> 8 using namespace std; 9 int n, m; 10 long long a[50100],l,r; 11 long long upp(int n,long long r) 12 { 13 int ll = 0, rr = n+1; 14 while (ll+1 < rr) 15 { 16 int mid = (ll + rr) / 2; 17 if (a[mid] <= r) ll = mid; 18 else rr = mid; 19 } 20 return rr; 21 } 22 long long downn(int n, long long l) 23 { 24 int ll = 0, rr = n; 25 while (ll + 1 < rr) 26 { 27 int mid = (ll + rr) / 2; 28 if (a[mid] >= l) rr = mid; 29 else ll = mid; 30 } 31 return ll; 32 } 33 int main() 34 { 35 int t; 36 cin >> t; 37 while (t--) 38 { 39 cin >> n >> m; 40 memset(a, 0, sizeof(a)); 41 for (int i = 1; i <= n; i++) 42 { 43 cin >> a[i]; 44 a[i] = a[i] * a[i]; 45 } 46 sort(a + 1, a + n + 1); 47 for (int i = 1; i <= m; i++) 48 { 49 cin >> l >> r; 50 cout << upper_bound(a+1,a+n+1,r)-lower_bound(a+1,a+n+1,l)<< endl; 51 } 52 } 53 return 0; 54 }View Code
C:Jeff與骰子游戲
Description
骰子大家一定都玩過。
一個骰子有六個面,每個面都有一個數字。對於骰子的每一個面,你都可以通過朝一個方向翻轉90度來獲得另一個面。
現在你有一個骰子,一開始朝上的一面點數為1(如圖上的第一個骰子所示)。
你每次都可以將它朝一個方向翻轉90度,並獲得相當於翻轉之後的骰子朝上一面的點數的分數。比如,現在骰子朝上的一面點數為1,你可以通過翻轉使它朝上的一面變成3,並獲得3分。
現在給出一個目標分數s,請問你至少需要翻轉幾次,使得你的分數剛好等於目標分數。
Input
題目包含多組測試資料。
第一行是一個整數T,表示有T組測試資料。
對於每組測試資料,只有一個正整數s,表示你需要達到的目標分數。(1 <= s <= 10000)
Output
對於每組測試資料,輸出達到目標分數至少需要翻轉幾次,如果無解請輸出-1。Examples
Input
2 5 10Output
1 2 Hint 對於第二組樣例: 你可以先翻轉90度,使得骰子朝上的一面變為4,並獲得4分。 之後你可以再翻轉90度,使得骰子朝上的一面變為6,並獲得6分。 所以你至少需要2步來達到目標分數。正確解法:
考試時覺得,每次骰子上面的數不確定,它能翻轉到達的數也不確定,要一個一個判斷,我覺得很麻煩,不會寫,但其實只要不是它本身,和底下的數 7-i 其他的數都可以到達。
於是就成了一個裸bfs。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 #include<algorithm> 7 using namespace std; 8 int n; 9 int book[100100]; 10 struct student 11 { 12 int shu, ci,daa; 13 }que[500100]; 14 int bfs(int n) 15 { 16 if (n == 1) return 0; 17 memset(book, 0, sizeof(book)); 18 memset(que, 0, sizeof(que)); 19 int head = 1, tail = 2; 20 que[head].shu = 1; 21 que[head].ci = 0; 22 que[head].daa = 0; 23 book[0] = 1; 24 while (head < tail) 25 { 26 if (que[head].daa == n) return que[head].ci; 27 for (int i = 1; i <= 6; i++) 28 { 29 if (que[head].shu == i || que[head].shu == 7 - i) 30 continue; 31 if (book[que[head].daa+i] == 0) 32 { 33 que[tail].shu = i; 34 que[tail].ci = que[head].ci + 1; 35 que[tail].daa = que[head].daa + i; 36 book[que[tail].daa] = 1; 37 if (que[tail].daa == n) return que[tail].ci; 38 tail++; 39 } 40 } 41 head++; 42 } 43 return -1; 44 } 45 int main() 46 { 47 int t; 48 cin >> t; 49 while (t--) 50 { 51 cin >> n; 52 cout << bfs(n) << endl; 53 } 54 return 0; 55 }View Code
我是傻逼,現在覺得這題都好簡單。為什麼寫不出來!
D:Rabbit尋寶記(2)
Description
Rabbit成功地打開了大門後,沒多久就見到了夢寐以求的寶藏。裡面的寶石種類共有N 種,每一種都有一個體積v 和它的價值val 。(已知第i 種寶石的體積為i ,編號從1 ~N )更讓Rabbit興奮的是,每種寶石的數量還是無窮無盡的。
Rabbit當然想把所有寶石全都帶回家,但是她帶的袋子卻最多隻能裝下總體積為V 的寶石,所以貪心的Rabbit決定要帶走總體積恰好為V 的寶石。
現在她突然想知道自己在拿走寶石數量恰好為N 的情況下總價值最大為多少?
Input
輸入資料第一行是一個正整數T ,表示資料組數。(T<=20 )
每組資料佔兩行。
第一行為兩個整數N,V 。(0<N<=1000,N<=V<=min(N∗N,2∗N) )
接下來一行有N個整數,代表N種寶石的價值vali 。(0<vali<=10000 )
Output
每組測試資料輸出一行,代表在滿足拿走寶石總體積恰為 V 和數量恰好為N 的情況下Rabbit能拿走寶石的最大總價值。Examples
Input
1 3 5 6 2 4Output
16正確解法:
動態規劃QAQ不會
Description
Jeff正在玩一種卡牌遊戲,在這個遊戲中,每個回合玩家可以執行以下兩種操作無數次:
1.使用一張手上的牌。
2.命令場上的一隻生物對敵方造成傷害,每一隻生物在一個回合內最多攻擊一次。
現在Jeff的場上擁有n只生物,第i只怪物擁有ai點攻擊力與bi點血量。
同時,Jeff手上有m張手牌。由於他的運氣實在太差了,他的所有手牌都只有一個功能——使場上一隻生物的攻擊力等於它的血量。
現在正是斬殺對手的關鍵回合,Jeff希望他能通過一種合理的策略,對敵方造成最高的傷害。請幫助Jeff計算他能造成的最高傷害。
Input
題目包含多組測試資料。
第一行是一個整數T,表示有T組測試資料。
對於每組測試資料,第一行包含兩個整數n,m(0 <= n,m <= 500),表示場上生物數量和手牌數量。
接下來的n行,每行包含兩個整數ai,bi(1 <= ai,bi <= 10000000),表示第i只怪物的攻擊力和血量。
Output
輸出Jeff在一個回合內能對敵方造成的最高傷害。Examples
Input
1 3 2 1 3 2 4 5 3Output
12 Hint 對於第一組樣例: Jeff可以先對場上第1只和第2只生物使用手牌,使得它們的攻擊力變成3和4。 然後Jeff命令所有生物攻擊,總共可以造成12點傷害。
正確解法:
原本就是全部加a[i],把b[i]-a[i] 排序,取出前m個在加起來,不知道為什麼wa
等待正解。
B:qw的表白
Description
qw喜歡上了一個美麗的女孩,並勇敢向她表白。但女神喜歡演算法厲害的男生,便給他出了一道題:
給定包含n 個整數的數列a 和m 個詢問,每個詢問包含兩個整數L ,R ,對於每一個詢問,要求輸出數列中有多少個數ai ,滿足L≤a2i≤R ,即有多少個數平方後取值範圍在[L,R] 之間。
單身二十年的qw非常想談戀愛,你能幫幫他嗎?
Input
多組資料。
第一行給出資料組數T(1≤T≤50 )
每組資料首先給定兩個整數n ,m ,表示數列中數的個數和詢問個數。(1≤n,m≤50000 )
隨後一行給出n 個整數 a1,a2,a3...an (1≤ai≤1e9 )
隨後m 行,每行兩個整數 L , R ,表示當前詢問的數值範圍區間。(1≤L≤R≤1e9 )
Output
對於每個詢問,單獨輸出一行,包含一個整數,表示數列中滿足條件的數個數Examples
Input
1 5 3 1 2 3 4 5 1 4 4 9 1 25Output
2 2 5正確解法:
我以為1e9 long long 會超,其實不會,那麼就很簡單
long long 排序,二分搜尋。
寫了半天二分搜尋,後面發現可能有一個二分函式,有點sad,但無論學了什麼都要保證自己會呀。
1 #include "pch.h" 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<string> 6 #include<cstring> 7 #include<algorithm> 8 using namespace std; 9 int n, m; 10 long long a[50100],l,r; 11 long long upp(int n,long long r) 12 { 13 int ll = 0, rr = n+1; 14 while (ll+1 < rr) 15 { 16 int mid = (ll + rr) / 2; 17 if (a[mid] <= r) ll = mid; 18 else rr = mid; 19 } 20 return rr; 21 } 22 long long downn(int n, long long l) 23 { 24 int ll = 0, rr = n; 25 while (ll + 1 < rr) 26 { 27 int mid = (ll + rr) / 2; 28 if (a[mid] >= l) rr = mid; 29 else ll = mid; 30 } 31 return ll; 32 } 33 int main() 34 { 35 int t; 36 cin >> t; 37 while (t--) 38 { 39 cin >> n >> m; 40 memset(a, 0, sizeof(a)); 41 for (int i = 1; i <= n; i++) 42 { 43 cin >> a[i]; 44 a[i] = a[i] * a[i]; 45 } 46 sort(a + 1, a + n + 1); 47 for (int i = 1; i <= m; i++) 48 { 49 cin >> l >> r; 50 cout << upp(n, r) - downn(n, l) - 1 << endl; 51 } 52 } 53 return 0; 54 }View Code
1 #include "pch.h" 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<string> 6 #include<cstring> 7 #include<algorithm> 8 using namespace std; 9 int n, m; 10 long long a[50100],l,r; 11 long long upp(int n,long long r) 12 { 13 int ll = 0, rr = n+1; 14 while (ll+1 < rr) 15 { 16 int mid = (ll + rr) / 2; 17 if (a[mid] <= r) ll = mid; 18 else rr = mid; 19 } 20 return rr; 21 } 22 long long downn(int n, long long l) 23 { 24 int ll = 0, rr = n; 25 while (ll + 1 < rr) 26 { 27 int mid = (ll + rr) / 2; 28 if (a[mid] >= l) rr = mid; 29 else ll = mid; 30 } 31 return ll; 32 } 33 int main() 34 { 35 int t; 36 cin >> t; 37 while (t--) 38 { 39 cin >> n >> m; 40 memset(a, 0, sizeof(a)); 41 for (int i = 1; i <= n; i++) 42 { 43 cin >> a[i]; 44 a[i] = a[i] * a[i]; 45 } 46 sort(a + 1, a + n + 1); 47 for (int i = 1; i <= m; i++) 48 { 49 cin >> l >> r; 50 cout << upper_bound(a+1,a+n+1,r)-lower_bound(a+1,a+n+1,l)<< endl; 51 } 52 } 53 return 0; 54 }View Code
C:Jeff與骰子游戲
Description
骰子大家一定都玩過。
一個骰子有六個面,每個面都有一個數字。對於骰子的每一個面,你都可以通過朝一個方向翻轉90度來獲得另一個面。
現在你有一個骰子,一開始朝上的一面點數為1(如圖上的第一個骰子所示)。
你每次都可以將它朝一個方向翻轉90度,並獲得相當於翻轉之後的骰子朝上一面的點數的分數。比如,現在骰子朝上的一面點數為1,你可以通過翻轉使它朝上的一面變成3,並獲得3分。
現在給出一個目標分數s,請問你至少需要翻轉幾次,使得你的分數剛好等於目標分數。
Input
題目包含多組測試資料。
第一行是一個整數T,表示有T組測試資料。
對於每組測試資料,只有一個正整數s,表示你需要達到的目標分數。(1 <= s <= 10000)
Output
對於每組測試資料,輸出達到目標分數至少需要翻轉幾次,如果無解請輸出-1。Examples
Input
2 5 10Output
1 2 Hint 對於第二組樣例: 你可以先翻轉90度,使得骰子朝上的一面變為4,並獲得4分。 之後你可以再翻轉90度,使得骰子朝上的一面變為6,並獲得6分。 所以你至少需要2步來達到目標分數。正確解法:
考試時覺得,每次骰子上面的數不確定,它能翻轉到達的數也不確定,要一個一個判斷,我覺得很麻煩,不會寫,但其實只要不是它本身,和底下的數 7-i 其他的數都可以到達。
於是就成了一個裸bfs。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 #include<algorithm> 7 using namespace std; 8 int n; 9 int book[100100]; 10 struct student 11 { 12 int shu, ci,daa; 13 }que[500100]; 14 int bfs(int n) 15 { 16 if (n == 1) return 0; 17 memset(book, 0, sizeof(book)); 18 memset(que, 0, sizeof(que)); 19 int head = 1, tail = 2; 20 que[head].shu = 1; 21 que[head].ci = 0; 22 que[head].daa = 0; 23 book[0] = 1; 24 while (head < tail) 25 { 26 if (que[head].daa == n) return que[head].ci; 27 for (int i = 1; i <= 6; i++) 28 { 29 if (que[head].shu == i || que[head].shu == 7 - i) 30 continue; 31 if (book[que[head].daa+i] == 0) 32 { 3