PTA团体程序设计天梯赛篇(四)----几何+算法专题
幾何+算法專題
- 算法
- 字符串算法
- 最長對稱子串(Manacher 算法)
- 動態規劃
- 至多刪三個字符
- 幾何
- 神壇(極角排序)
算法
字符串算法
最長對稱子串(Manacher 算法)
題目鏈接
解題思路
代碼
#include <iostream> #include <algorithm> #include <string> using namespace std; const int N = 2010; string s; int p[N], mx, id, ans;string motify(string s) {string str = "$";for (int i = 0 ; i < s.size() ; ++i)str += "#", str += s[i];str += "#";return str; }int main() {getline(cin, s);s = motify(s);for (int i = 1 ; i < s.size() ; ++i) {if (i < mx)p[i] = max(p[2 * id - i], mx - i);elsep[i] = 1;while (s[i - p[i]] == s[i + p[i]])p[i]++;if (i + p[i] > mx) {mx = p[i];id = i ;ans = max(ans, p[i] - 1);}}cout << ans << endl;return 0; }動態規劃
至多刪三個字符
題目鏈接
解題思路
dp[i][j]表示前i里面刪除了j個有多少種方法
第i個刪除或者不刪除有兩種情況
d p [ i ] [ j ] = d p [ i ? 1 ] [ j ] + d p [ i ? 1 ] [ j ? 1 ] dp[i][j] = dp[i-1][j]+dp[i-1][j-1]dp[i][j]=dp[i?1][j]+dp[i?1][j?1]
這樣會有重復
例如cc這種,需要去重,怎么去重呢,那就看什么情況多計算了
很顯然刪除 X…X (… 代表不知道幾個字符,X代表相同字符)
X…和 …X時最后剩下的都是X,會有重復
所以 這種情況需要去重復
當我們處理到i,j時,假設前面x處有一個相同字符,那么就用
d p [ i ] [ j ] ? = d p [ x ? 1 ] [ j ? ( i ? x ) ] dp[i][j] -= dp[x-1][j-(i-x)]dp[i][j]?=dp[x?1][j?(i?x)]
意思就是刪除x到i-1的字符這部分會有重復
代碼:
#include <iostream> #include <string> #include <cstring> #include <algorithm> using namespace std;const int N = 1E6 + 10;int n ; long long f[N][4]; char s[N];int main() {cin >> (s + 1);n = strlen(s + 1);f[0][0] = 1;for (int i = 1 ; i <= n ; ++i)for (int j = 0 ; j <= 3 ; ++j) {f[i][j] = f[i - 1][j];if (j)f[i][j] += f[i - 1][j - 1];for (int k = i - 1 ; k && (j - i + k) >= 0 ; --k) {int x = i - k;if (s[k] == s[i] ) {f[i][j] -= f[k - 1][j - x];break;}}}long long ans = 0;for (int j = 0 ; j <= 3 ; ++j)ans += f[n][j];cout << ans << endl;return 0; }幾何
神壇(極角排序)
解題思路:
極角排序 遍歷每個點和其余所有點向量 極角排序 找的相鄰兩條線段 求三角形面積。
這與為什么是與極角排序,是因為我們在求面積的時候是利用叉積來求的,而叉積的數組除了與向量長度有關之外,還有是兩個向量之間的夾角。因此我們按照極角排序之后,那么相鄰兩個向量進行叉積得到的結果肯定會比于其余的向量進行叉積的值更小。
我們依次以某一個點為極點來進行排序。之后遍歷取最小值。
代碼:
#include<bits/stdc++.h> using namespace std; typedef long long ll; struct node {ll x,y; }po[100005],poo[100005]; bool cmp(node a,node b) {return b.y*a.x > b.x*a.y; } int main() {int n;scanf("%d",&n);for(int i = 1;i <= n;i++){scanf("%lld%lld",&po[i].x,&po[i].y);}ll ans = 1e18;for(int i = 1;i <= n;i++){int p=0;for(int j = 1;j <= n;j++){if(i == j) continue;poo[p].x = po[j].x - po[i].x;poo[p].y = po[j].y - po[i].y;p++;}sort(poo,poo+p,cmp);for(int j = 1;j < p;j++){ans = min(ans,abs(poo[j].y*poo[j-1].x-poo[j].x*poo[j-1].y));}}printf("%.3f\n",ans/2.0);return 0; }總結
以上是生活随笔為你收集整理的PTA团体程序设计天梯赛篇(四)----几何+算法专题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: acwing----春季每日一题2022
- 下一篇: 算法篇之-----滑动窗口(尺取法)