Stack
Stack
知识
- push()、pop()、top()、empty()、size()
练手
-
有一个n个数的序列,判断这个序列能否是按照1~n的顺序入栈并随机出栈的结果。
#include <iostream> #include <stack> #include <vector> using namespace std; int main() { int n; cin >> n; vector<int> a(n); stack<int> s; int cur = 1; bool f = 1; for (int i = 0; i < n; i++) cin >> a[i]; for (int i = 0; i < n; i++) { while ((s.empty() || s.top() != a[i]) && cur <= n) { s.push(cur); cur++; } if (s.empty() || s.top() != a[i]) { f = 0; break; } else s.pop(); } if(f) cout << "legal" << endl; else cout << "illegal" << endl; return 0; } /* input: 5 1 3 2 5 4 output: legal */ /* input: 5 1 5 3 2 4 output: illegal */
递归
练手
-
计算阶乘
#include <iostream> using namespace std; long long factorial(int n) { if (n <= 1) { return 1; } return n * factorial(n - 1); } int main() { int n; cin >> n; cout << factorial(n) << endl; return 0; }
-
斐波那契数列
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> long long f(int x) { if (x <= 0) return 0; if (x == 1) return 1; if (x > 1 && x % 2 == 0) { return 3 * f(x / 2) - 1; } if (x > 1 && x % 2 == 1) { return 3 * f((x + 1) / 2) - 1; } } int main() { freopen("fx.in", "r", stdin); //文件输入输出 freopen("fx.out", "w", stdout); int x; long long ans; scanf("%d", &x); printf("%lld\n", f(x)); return 0; }
-
汉诺塔
#include <iostream> #include <stack> using namespace std; stack<int> S[3]; void move(int x, int y) { int temp = S[x].top(); S[x].pop(); S[y].push(temp); cout << x << "-->" << y << endl; } void hanoi(int A, int B, int C, int n) { if (n == 1) { move(A, C); return; } hanoi(A, C, B, n - 1); move(A, C); hanoi(B, A, C, n - 1); } int main() { int n; cin >> n; for (int i = n; i >= 1; i--) { S[0].push(i); } hanoi(0, 1, 2, n); while(!S[2].empty()) { cout << S[2].top() << " "; S[2].pop(); } }
-
每次吃剩下的一半多一个,第n天还剩一个,问最开始多少个
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> int n; int f(int x) { if (x == n) return 1; else return (f(x + 1) + 1) * 2; } int main() { scanf("%d", &n); printf("%d\n", f(1)); return 0; }
-
等号赋值后,返回的还是这个数
f 1 = f 2 = 1 , f n = a f n − 1 + b f n − 2 ( n > 2 ) f_1 = f_2 = 1, f_n = af_{n-1} + bf_{n-2}(n>2) f1=f2=1,fn=afn−1+bfn−2(n>2)
输入n(1<= n <=100), a(1<=a<=10), b(1<=b<=10), p(1<=p<=2000)。输出 f n f_n fn对p取模的值
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> int ans[2005]; bool vis[2005]; int f(int n, int a, int b, int p) { if (vis[n]) { return ans[n]; } vis[n] = true; if (n == 1 || n == 2) { return ans[n] = 1 % p; }else { return ans[n] = (a * f(n - 1, a, b, p) % p + b * f(n-2, a, b, p) %p) % p; } } int main() { int n, a, b, p; scanf("%d%d%d%d", &n, &a, &b, &p); printf("%d\n", f(n, a, b, p)); return 0; } /* 输入: 3 1 1 1000 输出: 2 输入: 5 2 2 1233 输出: 28 */
-
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> long long f(long long x, long long y, long long p) { if (y == 0) { return 1 % p; } else if (y % 2 == 0) { long long temp = f(x, y / 2, p); return temp * temp % p; } else { long long temp = f(x, y / 2, p); return temp * temp % p * x % p; //乘一下取一下模,防止爆栈 } } int main() { int t; long long x, y, p; scanf("%d", &t); while(t--) { scanf("%lld%lld%lld", &x, &y, &p); printf("%lld\n", f(x, y, p)); } return 0; } /* input: 1 2 10 10000 output: 1024 */
-
跳格子,每个格子上有两种前进格数的选择,共n个格子,怎么能用最少次数跳出去。
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <algorithm> using namespace std; int a[205], b[205]; int ans[205]; bool vis[205]; int n; int f(int x) { if (x >= n) { return 0; } if(vis[x]) { return ans[x]; } vis[x] = true; return ans[x] = min(f(x + a[x]), f(x+b[x])) + 1; } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &a[i]); } for (int i = 0; i < n; i++) { scanf("%d", &b[i]); } printf("%d\n", f(0)); } /* input: 5 2 2 3 1 2 1 2 3 4 1 output: 2 */
-
最大公约数
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> int gcd(int x, int y) { if (y == 0) { return x; }else { return gcd(y, x % y); } } int main() { int t; int x, y; scanf("%d", &t); //t组输入 while(t--) { scanf("%d%d", &x, &y); printf("%d\n", gcd(x, y)); } return 0; }
-
括号匹配
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <stack> using namespace std; char s[50005]; stack<int> S; int ans[50005]; int main() { int len; bool f; scanf("%s", &s); len = strlen(s); f = true; for (int i = 0; i < len; i++) { if (s[i] == '(') { S.push(i + 1); }else { if (!S.empty()) { ans[i + 1] = S.top(); S.pop(); }else { f = false; break; } } } if (!S.empty()) { f = false; } if (!f) { printf("No\n"); }else { printf("Yes\n"); for (int i = 1; i <= len; i++) { if(ans[i]) { printf("%d %d\n", ans[i], i); } } } return 0; } /* input: (()) output: Yes 2 3 1 4 */
-
浏览器三种操作:打开页面:输入网址并跳转到对应页面;回退:返回到上一次访问的页面;前进:返回到上次回退前的页面,如果上次操作是打开页面,则无法前进。
输入:整数0<n<=100000,操作次数。n行:字符串,如果是VISIT,接着输入一个不包含空格和换行的长度小于100的网址;如果是BACK,则回退;如果是FORWARD,则前进。
对于每次操作:成功则输出网址,否则输出Ignore
#include <iostream> #include <stack> #include <string> using namespace std; string op, s; stack<string> s1, s2; int main() { int n; cin >> n; for (int i = 0; i < n; i++) { cin >> op; if (op == "VISIT") { cin >> s; while(!s2.empty()) { s2.pop(); } s1.push(s); } else if(op == "BACK") { if(s1.size() <= 1) { cout << "Ignore" << endl; continue; } s2.push(s1.top()); s1.pop(); } else { if (s2.empty()) { cout << "Ignore" << endl; continue; } s1.push(s2.top()); s2.pop(); } cout << s1.top() << endl; } return 0; }