2.25-3.2 周记
生活随笔
收集整理的這篇文章主要介紹了
2.25-3.2 周记
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2.25-3.2
1. 計算幾何
1.1 二維幾何基礎
struct Point{double x,y;Point(double x = 0, double y = 0):x(x),y(y){} } typedef Point Vector; Vector operator + (Vector A ,Vector B){ return Vector(A.x+B.x,A.y+B.y); } Vector operator - (Vector A ,Vector B){ return Vector(A.x-B.x,A.y-B.y); } Vector operator / (Vector A ,Vector B){ return Vector(A.x/B.x,A.y/B.y); } Vector operator * (Vector A ,Vector B){ return Vector(A.x*B.x,A.y*B.y); } bool operator < (const Point &a,const Point &b){return a.x<b.x||(a.x==b.x&&a.y<b.y); } const double eps = 1e-10; int dcmp(double x){if(fabs(x)<eps) return 0;else return x<0?-1:1; } bool operator == (const Point &a,const Point &b){return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0; } //atan2計算極角1.1.1 基本運算
double Dot(Vector A,Vector B){ return A.x*B.x+A.y*B.y; } double Length(Vector A){return sqrt(Dot(A,A)); } double Angle(Vector A,Vector B){ return acos(Dot(A,B)/Length(A)/Length(B)); } double Cross(Vector A,Vector B){ return A.x*B.y - A.y*B.x;} double Area2(Point A,Point B,Point C){ return Cross(B-A,C-A); }Vector Rotate(Vector A,double rad){return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad)); } Vector Normal(Vector A){double L = Length(A);return Vector(-A.y/L,A.x/L); }1.1.2 點與直線
//直線用P = P0+tv表示 //調用前確保兩條直線P+tv,Q+tw有唯一交點,當且僅當Cross(v,w)非0 Point GetLineIntersection(Point P,Vector v,Point Q,Vector w){Vector u = P-Q;double t = Cross(w,u)/Cross(v,w);return p+v*t; }double DistanceToLine(Point P,Point A,Point B){Vector v1 = B-A,v2 = P-A;return fabs(Cross(v1,v2))/Length(v1);//不取絕對值得到有向距離 }double DistanceToSegment(Point P,Point A,Point B){if(A==B)return Length(P-A);Vector v1 = B-A,v2 = P-A,v3 = P-B;if(dcmp(Dot(v1,v2)) < 0)return Length(v2);else if(dcmp(Dot(v1,v3)) > 0)return Length(v3);else return fabs(Cross(v1,v2))/Length(v1); }//點在直線上的投影 Point GetLineProjection(Point p,Point A,Point B){Vector v = B-A;return A+v*(Dot(v,P-A)/Dot(v,v)); } //線段相交 嚴格相交 bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2){double c1 = Cross(a2-a1,b1-a1),c2 = Cross(a2-a1,b2-a1);double c3 = Cross(b2-b1,a1-b1),c4 = Cross(b2-b1,a2-b1);return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0; } //不嚴格相交,還沒有補充 bool Onsegment(Point p,Point a1,Point a2){return dcmp(Cross(a1-p,a2-p))==0 && dcmp(Dot(a1-p,a2-p)) < 0; }1.1.3 多邊形
//多邊形 double ConvexPolygonArea(Point *p,int n){double area = 0;for(int i=1;i<n-1;i++)area += Cross(p[i]-p[0],p[i+1]-p[0]);return area/2; } double PolygonArea(Point *p,int n){return ConvexPolygonArea(P,n); }1.2 與圓有關的計算問題
2. CF-1130
D題和E題
- 火車只能順時針走
- 一次只能從一個地方拿走一個,所以對于當前 j ,如果有cnt[j]個糖果,那么必須經過它cnt[j]次,而且把需要傳遞距離最近的那個留到最后。這樣該點需要走的最遠距離就是(cnt[j]-1)*n + last ,last為最后一個要走的距離。
- \(O(n^2)\) 遍歷所有。輸出答案
3. CF-1038
C - Gambling
- 這題很簡單,貪心就可以了,奈何我腦癡把數組下標寫的小了,浪費了二十分鐘
D - Slime
- 每個數給答案的貢獻無非只有兩種,一種正的,一種負的,讓我們想想極端的情況。假如這個序列整個都是正的,那我們需要一個數來充當被減數,然后之后整個序列就可以進行運算了。當我們運算出當前結果時,可以想到的是,該結果可以進行內部取反,來迎合下一次操作。(妙啊)
4. CF-1025
B - Weakened Common Divisor
- 這個題差點就想出來了,然而我太著急。
- 每組兩個數字,從中取出一個,然后整個序列很n個組,使得取出來的這n個數字的gcd不為1
- 因為每組兩個數字都可以取,所以可以提供的質因子就變成了兩份,為了產生對答案的貢獻,我們不妨把該組可以產生的貢獻都計算進去。然后篩選出來的答案再進行壓縮,使得他符合所有組中的選擇。
- 每組的數乘起來,然后求整個序列的gcd,可以想到這個gcd包含了所有組中共有的質因數(質因數的指數是多少不用管)。然后每次篩的時候,選一個質因數不為一的數字選就可以了。
C - Plasticine zebra
- 取一個切點然后反轉,兩次反轉我們可以發現完全就是將前綴串接到了后綴串的后面,而一次反轉效果也是同樣的,把切割點分開,兩端連上,中間的情況我們不需要考慮。
- 所以這個題就轉換為了把這個串結成一個圈,然后在圈上取一段長度最長不超過n的連續不同序列。注意極端情況(如果不是cf給的數據,恐怕要卡很久)
D - Recovering BST
- 區間dp,思路挺順,但是有一點馬虎了之后就會造成很大的麻煩
- dp[l][r][0]表示以 l-1 為根的區間可否組成二叉搜索樹。然后搜就可以了
- 代碼可以優化一下
壓縮后:
#include <bits/stdc++.h> using namespace std; const int N = 770; int n; int d[N][N][2],g[N][N],a[N]; int gcd(int a,int b){return b==0?a:gcd(b,a%b); } int dp(int l,int r,int m){int p = m==0?l:r;int &res = d[l][r][m];if(res)return res;if(l==r) res = 1;else{l = m==0?l+1:l;r = m==1?r-1:r;int flag = 0;for(int i=l;i<=r;i++){if(g[i][p]>1){if(dp(l,i,1)==1&&dp(i,r,0)==1){flag = 1;break;}}}if(flag)res = 1;else res = -1;}return res == 1; } int main(){cin>>n;for(int i=1;i<=n;i++){scanf("%d",&a[i]);g[i][i] = a[i];}for(int i=1;i<=n;i++)for(int j=i+1;j<=n;j++){g[i][j] = g[j][i] = gcd(a[i],a[j]);}int flag = 0;for(int i=1;i<=n;i++){if(dp(1,i,1)==1&&dp(i,n,0)==1){flag = 1;break;}}if(flag)puts("Yes");else puts("No");return 0; }5. CF-1027
B - Numbers on the Chessboard
- 思路還是比較清晰的,不過在處理各種情況時,不要一味想著統一所有情況,其實分一下奇偶也是可以的,更容易寫對
C - Minimum Value Rectangle
- 雖然是個難度1600的貪心,但是貪心策略很好想,難點在于處理上,如果用hash存儲的話,即使是1e4的數組,每組test memset一下時間也會爆炸,貌似有人卡過的,不過這不是正解。
- 正解是先排個序,然后兩個相同的變成一個,單著的就拋棄了就可以了。然后掃一次
- T了半小時之后看正解,因為數組下標,還有循環,又坑了半小時。感覺狀態不太好的時候就不要硬干了,肯定是小問題。
D - Mouse Hunt
- 這題一眼就是并查集,NONONO,忽略了兩點的有向關系。也是巧了,剛做了這題第二天就在牛客碰到了。
- 具體處理就是先拓撲掃一遍,剩下的就是環,在環內找個最小值放哨兵就可以了。
6.CF-1023
A - Single Wildcard Pattern Matching
- 被A題卡特判了。難過
大佬的代碼:
#include <bits/stdc++.h> using namespace std; int main() {string s1,s2;int n,m,i=0;cin>>n>>m>>s1>>s2;while(s1[i]==s2[i]&&i<min(m,n))i++;while(s1[n-1]==s2[m-1]&&i<min(m,n)){n--;m--;}return cout<<(s1[i]=='*'&&n-i==1||s1==s2?"YES":"NO"),0; }C - Bracket Subsequence
- 直接放代碼了,這題沒什么好說的,還卡了那么久。
轉載于:https://www.cnblogs.com/1625--H/p/10461355.html
總結
以上是生活随笔為你收集整理的2.25-3.2 周记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Docker+mysql
- 下一篇: Java中的容器