題目列表:
2146 Problem A | 【手速】闊綽的Dim |
2147 Problem B | 【手速】頹廢的Dim |
2148 Problem C | 【手速】我的滑板鞋 |
2149 Problem D | 【手速】潦倒的Dim |
2150 Problem E | 【手速】被NTR的Dim |
?
?2146 Problem A:
簡單的最長回文串統計算法,這里沒有過高要求,n^2算法可以AC。其中包括dp動規以及中心法(以上兩種都是O(n^2)算法,可以參考白書)。推廣,可以嘗試擴展KMP(O(nlogn))或者Manacher算法(O(n))。可以查閱相關資料自行選擇學習。這里給出中心法。
?
1 /****************************************/ 2 /***** Desgard_Duan *****/ 3 /****************************************/ 4 //#pragma comment(linker, "/STACK:102400000,102400000") 5 #define _CRT_SECURE_NO_WARNINGS 6 #include <iostream> 7 #include <cstdio> 8 #include <cstdlib> 9 #include <cstring> 10 #include <string> 11 #include <algorithm> 12 #include <stack> 13 #include <map> 14 #include <queue> 15 #include <vector> 16 #include <set> 17 #include <functional> 18 #include <cmath> 19 #include <numeric> 20 21 using namespace std; 22 23 char s[500]; int len; 24 25 inline void get_val(int &a) { 26 int value = 0, s = 1; 27 char c; 28 while ((c = getchar()) == ' ' || c == '\n'); 29 if (c == '-') s = -s; else value = c - 48; 30 while ((c = getchar()) >= '0' && c <= '9') 31 value = value * 10 + c - 48; 32 a = s * value; 33 } 34 35 int tofind(int h, int t) { 36 int re = t - h + 1; 37 while (h < t) { 38 if (s[h++] != s[t--]) return 0; 39 } 40 return re; 41 } 42 43 int main() { 44 //freopen("huiwen.in", "r", stdin); 45 //freopen("huiwen.out","w",stdout); 46 int T; 47 cin >> T; 48 while (T--) { 49 scanf("%s", s); 50 len = strlen(s); 51 int ans = 1; 52 for (int i = 0; i < len - 1; i++) 53 for (int j = i + 1; j < len; j++) { 54 ans = max(ans, tofind(i, j)); 55 } 56 cout << ans << endl; 57 } 58 return 0; 59 }
?
?
2147 Problem B:
一道字符串水題,只要按位置遍歷一遍即可。C語言基礎題。
1 /****************************************/ 2 /***** Desgard_Duan *****/ 3 /****************************************/ 4 //#pragma comment(linker, "/STACK:102400000,102400000") 5 #define _CRT_SECURE_NO_WARNINGS 6 #include <iostream> 7 #include <cstdio> 8 #include <cstdlib> 9 #include <cstring> 10 #include <string> 11 #include <algorithm> 12 #include <stack> 13 #include <map> 14 #include <queue> 15 #include <vector> 16 #include <set> 17 #include <functional> 18 #include <cmath> 19 #include <numeric> 20 21 using namespace std; 22 23 inline void get_val(int &a) { 24 int value = 0, s = 1; 25 char c; 26 while ((c = getchar()) == ' ' || c == '\n'); 27 if (c == '-') s = -s; 28 else value = c - 48; 29 while ((c = getchar()) >= '0' && c <= '9') 30 value = value * 10 + c - 48; 31 a = s * value; 32 } 33 34 string str1, str2; 35 int main () { 36 int T; 37 //cin >> T; 38 while (cin >> str1 >> str2) { 39 40 int ans = 0; 41 for (int i = 0 ; i < str1.size(); ++ i) { 42 if (str1[i] == str2[i]) { 43 ans ++; 44 } 45 } 46 cout << ans << endl; 47 } 48 return 0; 49 }
?
2148 Problem C:
一道貪心的白書例題,類型歸類為查找不相交區間的最大個數。具體思路:對于相交的任意兩個區間分為兩種情況(圖A、圖B)。若出現情況A,直接將大區間刪除即可。若出現情況B,我們先將集合按照x進行升序排列,然后優先選取x最小的情況B中的區間,這樣可以得到最佳的方案。
1 /****************************************/ 2 /***** Desgard_Duan *****/ 3 /****************************************/ 4 //#pragma comment(linker, "/STACK:102400000,102400000") 5 #define _CRT_SECURE_NO_WARNINGS 6 #include <iostream> 7 #include <cstdio> 8 #include <cstdlib> 9 #include <cstring> 10 #include <string> 11 #include <algorithm> 12 #include <stack> 13 #include <map> 14 #include <queue> 15 #include <vector> 16 #include <set> 17 #include <functional> 18 #include <cmath> 19 #include <numeric> 20 21 using namespace std; 22 23 inline void get_val(int &a) { 24 int value = 0, s = 1; 25 char c; 26 while ((c = getchar()) == ' ' || c == '\n'); 27 if (c == '-') s = -s; 28 else value = c - 48; 29 while ((c = getchar()) >= '0' && c <= '9') 30 value = value * 10 + c - 48; 31 a = s * value; 32 } 33 34 vector<pair<int, int> > shoes; 35 bool flag[1005]; 36 37 int main () { 38 int n, x, y; 39 //freopen("out.txt", "w", stdout); 40 while (~scanf ("%d", &n)) { 41 shoes.clear(); 42 for (int i = 0; i < n; ++ i) { 43 cin >> x >> y; 44 shoes.push_back (make_pair(x, y)); 45 } 46 sort (shoes.begin(), shoes.end()); 47 48 memset (flag, 0, sizeof (flag)); 49 for (int i = 0; i < n; ++ i) { 50 if (flag[i]) { 51 continue; 52 } 53 for (int j = 0; j < n; ++ j) { 54 if (i == j) continue; 55 else { 56 if (shoes[i].first <= shoes[j].first && shoes[i].second >= shoes[j].second) { 57 flag[i] = 1; 58 } 59 } 60 } 61 } 62 int cur = 0, ans = 1; 63 for (; cur < shoes.size() && flag[cur]; cur ++); 64 int last_end = shoes[cur].second, this_begin; 65 for (int i = cur + 1; i < shoes.size(); ++ i) { 66 if (flag[i]) continue; 67 this_begin = shoes[i].first; 68 if (last_end <= this_begin) { 69 ans ++; 70 last_end = shoes[i].second; 71 } 72 } 73 cout << ans << endl; 74 75 } 76 return 0; 77 }
?
2149 Problem D:
一道大數題目。在n個大數中尋找最小的數。大數推薦使用Java大數類,相對來說代碼比較清晰。也可以直接開一個數組進行模擬。
?
1 import java.math.*; 2 import java.io.*; 3 import java.util.*; 4 5 public class Main { 6 public static void main(String args[]) { 7 Scanner in = new Scanner(System.in); 8 while (in.hasNext()) { 9 int n = in.nextInt(); 10 BigInteger ans = BigInteger.ZERO; 11 for (int i = 0; i < n; ++i) { 12 BigInteger a = in.nextBigInteger(); 13 if (i == 0) { 14 ans = a; 15 } else { 16 ans = ans.min(a); 17 } 18 } 19 System.out.println (ans); 20 } 21 } 22 }
?
?
2150 Problem E:
一道簡單的數學題目。稍微推導一下就會發現這個函數最多只有六項。分別是a, b, b - a, -a, -b, a - b六個數,只要我們去一下重復的數即可。去重方法可以用一個字符串數組來做,這里用了set容器的性質進行了去重操作。
1 /****************************************/ 2 /***** Desgard_Duan *****/ 3 /****************************************/ 4 //#pragma comment(linker, "/STACK:102400000,102400000") 5 #define _CRT_SECURE_NO_WARNINGS 6 #include <iostream> 7 #include <cstdio> 8 #include <cstdlib> 9 #include <cstring> 10 #include <string> 11 #include <algorithm> 12 #include <stack> 13 #include <map> 14 #include <queue> 15 #include <vector> 16 #include <set> 17 #include <functional> 18 #include <cmath> 19 #include <numeric> 20 21 using namespace std; 22 23 inline void get_val(int &a) { 24 int value = 0, s = 1; 25 char c; 26 while ((c = getchar()) == ' ' || c == '\n'); 27 if (c == '-') s = -s; 28 else value = c - 48; 29 while ((c = getchar()) >= '0' && c <= '9') 30 value = value * 10 + c - 48; 31 a = s * value; 32 } 33 34 35 int a, b, n; 36 set<int> S; 37 int main () { 38 while (cin >> a >> b >> n) { 39 S.clear(); 40 if (n >= 6) { 41 S.insert (a); 42 S.insert (b); 43 S.insert (b - a); 44 S.insert (-a); 45 S.insert (-b); 46 S.insert (a - b); 47 cout << S.size() << endl; 48 continue; 49 } else { 50 int last = a, now = b, t; 51 S.insert (a); 52 S.insert (b); 53 for (int i = 3; i <= n; ++ i) { 54 S.insert (now - last); 55 t = now; 56 now = now - last; 57 last = t; 58 } 59 cout << S.size() << endl; 60 } 61 } 62 return 0; 63 }
?
?
最后,感謝這次的命題者:王浩宇(stdiohero),葉鵬(yeahpeng),王馳(wid),謝文亮(Dim),朱吳帥(JM)同學為我們出的這套熱身題目。祝大家在參賽后有所提高。謝謝大家。
——Desgard_Duan
2014.10.31