日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PTA团体程序设计天梯赛篇(四)----几何+算法专题

發布時間:2025/3/19 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PTA团体程序设计天梯赛篇(四)----几何+算法专题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

幾何+算法專題

  • 算法
    • 字符串算法
      • 最長對稱子串(Manacher 算法)
    • 動態規劃
      • 至多刪三個字符
  • 幾何
    • 神壇(極角排序)

算法

字符串算法

最長對稱子串(Manacher 算法)

題目鏈接
解題思路

  • 在進行馬拉車算法之前,我們需要將字符串進行處理,第一個就是在原字符串的首部和尾部加特殊字符 ,以及每兩個字符之間加上相同的特殊字符。這樣做的目的是將字符串個數變為奇數方便處理。同時再在最頭部放上一個不一樣的另一個特殊字符,只有的目的是在判斷是否對稱的時候不會越界。
  • 有人說KMP算法和Manacher 算法有點類似。總某些方面來說確實是這樣的。在KMP算法中的next數組是以該字符為結尾滿足條件的最大長度。(具體可以搜所),在Manacher 算法中求的p數組是以該字符為中心,右邊距離最長的對稱字符的最長距離。
  • 對于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团体程序设计天梯赛篇(四)----几何+算法专题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。