【Luogu】【关卡2-13】线性数据结构(2017年10月)【还差一道题】
任务说明:数组,链表,队列,栈,都是线性结构。巧用这些结构可以做出不少方便的事情。
P1996 约瑟夫问题
n个人,排成环形,喊到m的人出列,输出出列顺序。
咳咳,这个题目不好写,尽管简单就是模拟题...但是orz 乱七八糟加上debug的时间一共花了四十多分钟....
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <climits> 5 #include <stack> 6 #include <string> 7 using namespace std; 8 9 const int INF = 1000; 10 int main () { 11 int n, m; 12 cin >> n >> m; 13 vector<int> vec(n+1, 0); 14 vec[0] = INF; 15 int out = 0, ptr = 0, number = 0; 16 while(out < n) { 17 if (ptr > n) { ptr = ptr % n; } 18 if (number == m) { 19 /* 20 if (vec[ptr] == INF) { 21 cout << "\nexception \n"; 22 printf("ptr[%d]\n", ptr); 23 for (int ele = 0; ele <= n; ++ele) { 24 printf("%5-d", ele); 25 } 26 printf("\n"); 27 for (auto ele : vec) { 28 printf("%5-d", ele); 29 } 30 cout << endl; 31 return 0; 32 } 33 */ 34 cout << ptr << " " ; 35 number = 0; 36 vec[ptr] = INF; 37 ++out; 38 } else { 39 //printf("=======debug========number[%d], ptr[%d]\n", number, ptr); 40 ++ptr; 41 if (ptr > n) { ptr = ptr % n; } 42 while(vec[ptr] == INF) { 43 ++ptr; 44 if (ptr > n) { ptr = ptr % n; } 45 } 46 ++number; 47 } 48 } 49 if (out) { 50 cout << endl; 51 } 52 return 0; 53 }
有空看看题解优化下代码..
P1115 最大子段和
做了这个题才颠覆了我对最大字段和的认识。
以前默认的解法就是用dp[i] 表示 a[0..i] 的和,然后用二重循环相减,求出最大子段和。
提交了发现才过了两个点,剩下的三个点TLE。
然后看了题解才发现原来可以这么做:就是用一个变量来记录读进来数字的当前子段和,如果发现这个变量(当前子段和)比零小,那么就把它置0。因为后面那一坨不论是啥,前面加个负数都不划算,所以这么解最优。
时间复杂度O(N), 空间复杂度O(1)
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <climits> 5 using namespace std; 6 7 int main () { 8 int n; 9 cin >> n; 10 int ans = INT_MIN, dp = 0; 11 for (int i = 1; i <= n; ++i) { 12 int x; 13 cin >> x; 14 if (i == 1) { 15 dp = ans = x; 16 } else { 17 dp = dp + x > 0 ? dp + x : x; 18 } 19 ans = max(ans, dp); 20 } 21 cout << ans << endl; 22 return 0; 23 }
P1739 表达式括号匹配
简单题,不用复习,就是给个字符串,判断左右括号是否匹配。字符串没有空格隔开,直接cin就好。
提交一次AC了。
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <climits> 5 #include <stack> 6 #include <string> 7 using namespace std; 8 9 int main () { 10 stack<char> stk; 11 string str; 12 cin >> str; 13 for (auto ele : str) { 14 if (ele == '@') { 15 if (stk.empty()) { 16 cout << "YES" << endl; 17 } else { 18 cout << "NO" << endl; 19 } 20 return 0; 21 } 22 if (ele == '(') { 23 stk.push(ele); 24 } 25 if (ele == ')') { 26 if (stk.empty()) { 27 cout << "NO" << endl; 28 return 0; 29 } 30 stk.pop(); 31 } 32 } 33 return 0; 34 }
队列安排
P1449 后缀表达式
后缀表达式求值,用栈做。注意- 和/的时候top出来的两个变量顺序。要是考到,直接用个减法当例子。
提交一次AC了。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <vector> 5 #include <climits> 6 #include <stack> 7 #include <string> 8 #include <sstream> 9 using namespace std; 10 11 int getNextOper(string& str, int& idx) { 12 string strOper; 13 for (int i = idx; i < str.size(); ++i) { 14 if (str[i] == '.') { 15 idx = i + 1; 16 break; 17 } 18 if (!isdigit(str[i])) { 19 printf("exception\n\n"); 20 exit(-1); 21 } 22 strOper += str[i]; 23 } 24 stringstream ss(strOper); 25 int ans; 26 ss >> ans; 27 return ans; 28 29 } 30 31 int main () { 32 stack<int> stk; 33 string str; 34 cin >> str; 35 int startIdx = 0; 36 int iOper = getNextOper(str, startIdx); 37 stk.push(iOper); 38 39 int answer = 0; 40 while (str[startIdx] != '@') { 41 if (isdigit(str[startIdx])) { 42 int iOper = getNextOper(str, startIdx); 43 stk.push(iOper); 44 } else { 45 if (stk.size() < 2) { 46 printf("exception \n\n"); 47 } 48 int a = stk.top(); stk.pop(); 49 int b = stk.top(); stk.pop(); 50 if (str[startIdx] == '+') { 51 answer = a + b; 52 } 53 if (str[startIdx] == '-') { 54 answer = b - a; 55 } 56 if (str[startIdx] == '*') { 57 answer = a * b; 58 } 59 if (str[startIdx] == '/') { 60 answer = b / a; 61 } 62 startIdx++; 63 stk.push(answer); 64 } 65 } 66 cout << stk.top() << endl; 67 return 0; 68 }