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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

东北大学第二场算法题解报告

發(fā)布時間:2024/3/13 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 东北大学第二场算法题解报告 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

7-1 N個數求和

題解
按照小學學的分數,將輸入的分數全部通分,然后分子分母求最大公約數化簡
由題目知分數輸入的時候均以 分子/分母 給出,我們可以利用 scanf 中的格式符進行輸入
代碼

#include<iostream> #include<cstdio> #include<cmath> using namespace std; long long gcd(long long x,long long y) { if(y<0)return gcd(x,-y); if(!y)return x; else return gcd(y,x%y); } struct FS{ long long Fz,Fm; }a[105]; long long FFm=1,FFz=0; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;++i)scanf("%lld/%lld",&a[i].Fz,&a[i].Fm); for(int i=1;i<=n;++i) { long long k=gcd(FFm,a[i].Fm); FFm=FFm/k*a[i].Fm;//求出所有分母的最小公倍數 } for(int i=1;i<=n;++i)FFz+=FFm/a[i].Fm*a[i].Fz;//通分后的分子求和 if(!FFz)//分子為0的情況 { printf("0"); return 0; } long long ZZZ=gcd(FFm,FFz); FFm/=ZZZ; FFz/=ZZZ; if(FFz*FFz<FFm*FFm)//分子絕對值小于分母絕對值的情況 { printf("%lld/%lld",FFz,FFm); return 0; } long long A,B; B=FFz%FFm; A=FFz/FFm; printf("%lld",A); if(B)printf(" %lld/%lld",B,FFm); return 0; }

7-2 比較大小

題解
我這怎么寫題解……
可以使用C艸的algorithm里面的sort搞個排序真實大材小用
也可以手寫冒泡真實大材小用*2
也可以分類討論
或者搞個二叉搜索樹啥的(x)
代碼

7-3 A-B

題解
讀入兩個字符串,同時申請一個大小為128的布爾(bool)型數組
(可見的ASCII碼和空白字符在ascii碼表上占據32~126)
先讀入兩個字符串,并單獨掃一遍B字符串,B字符串出現過的字符在之前申請的bool型數組上做標記
再逐個字符檢查A字符串,當檢查的字符沒在布爾型數組上做過標記的時候才輸出
代碼

#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int a[3]; int main() { scanf("%d%d%d",&a[0],&a[1],&a[2]); sort(a,a+3);//我偷懶了直接丟了個sort上去 printf("%d->%d->%d",a[0],a[1],a[2]); return 0; } #include<iostream> #include<cstdio> #include<cstring> using namespace std; char A[10005]; char B[10005]; bool N[128]; ## 7-4 計算指數 題解 n不超過10,直接暴力循環(huán)可得也不會TLE (但建議學習一下快速冪算法,代碼中使用的即為快速冪算法) 代碼 int main() { for(int i=0;;++i) { A[i]=getchar(); if(A[i]=='\n')break; } for(int i=0;;++i) { B[i]=getchar(); if(B[i]=='\n')break; } for(int i=0;B[i]!='\n';++i)N[(int)B[i]]=true; for(int i=0;A[i]!='\n';++i) { if(!N[A[i]])printf("%c",A[i]); } return 0; } #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int Pow4(int a,int b) { int r=1; while(b) { if(b&1)r*=a; a*=a; b>>=1; } return r; } int main() { int n; scanf("%d",&n); printf("2^%d = %d",n,Pow4(2,n)); return 0; }

7-5 計算階乘和

題解
直接循環(huán)暴力求解即可
代碼

7-6 簡單題

題解
此題+巖漿=黑曜石
直接輸出即可
代碼

7-7 跟奧巴馬一起畫方塊

#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int main() { int n,t=1,S=0; scanf("%d",&n); for(int i=1;i<=n;++i) { t*=i; S+=t; } printf("%d",S); return 0; } #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int main() { printf("This is a simple problem."); return 0; }

題解
我咋感覺這個題之前在學校做過
按照題目要求循環(huán)就好了
代碼

7-8 查驗身份證

題解
按照題目要求直接做就好了
(別忘了申請兩個常數數組把加的權和對應的碼放進去)
代碼

#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; char a; int main() { int n,x; scanf("%d %c",&n,&a); x=(n+1)/2; for(int i=1;i<=x;++i) { for(int j=1;j<=n;++j) { printf("%c",a); } printf("\n"); } return 0; }

7-9 集合相似度

題解
其實也是個按照題面做就行的題,不過群里有人說超時,我在這說點解決方法
輸入結束后將每個集合內的數據從小到大排序(推薦學習一下快速排序,C艸用戶可直接使用STL內的
sort)
然后將集合內重復數據去除(可以暴力做,C艸用戶可直接使用STL內的unique)
這樣每個集合的大小都是已知的
排序的用途:找相同數據數目的時候,可以先定義兩個變量i,j。
分別指代兩個數組(下文分別稱之為A,B)的下標(i,j別忘記初始化)
然后如果A[i]>B[j],我們只需要將j+=1;
同理,如果A[i]<B[j] ,我們只需要將i+=1。
A[i]==B[j]時,我們計數+=1(即Nc+=1)同時i+=1, j+=1
當任意一個下標掃完整個數組后停止尋找
(因為此時每個數組內的數據是由小到大排序的且無重復數據,若A[i]>B[j] ,那么B數組內有可能等于
A[i]的數據只可能在B[j]之后,若B數組檢查完畢,則A當前數字以及之后的數組均不存在與B數組中,反
過來也是同理,不再贅述)
此時計算Nc所需時間為O(min(A數組元素數目,B數組元素數目))

#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; const char ST[11]={'1','0','X','9','8','7','6','5','4','3','2'}; const int St[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2}; char A[20]; int main() { int n; bool OK=true; scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%s",A); int Tem=0; bool OK2=true; for(int j=0;j<17;++j) { if(A[j]>='0'&&A[j]<='9') { Tem+=(A[j]-'0')*St[j]; } else { OK2=false; break; } } Tem%=11; if(!OK2||ST[Tem]!=A[17]) { printf("%s\n",A); OK=false; continue; } } if(OK)printf("All passed"); return 0; }

Nt=兩個數組元素數目之和-Nc
代碼

7-10 樹的遍歷

解題必備知識
二叉樹的定義,二叉樹先序、中序、后序和層序遍歷的定義與性質

#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int a[51][10005]; int main() { int N,K; scanf("%d",&N); for(int i=1;i<=N;++i) { int M; scanf("%d",&M); for(int j=1;j<=M;++j) { scanf("%d",&a[i][j]); } sort(a[i]+1,a[i]+M+1); a[i][0]=unique(a[i]+1,a[i]+M+1)-&a[i][1]; } scanf("%d",&K); while(K--) { int ta,tb; scanf("%d%d",&ta,&tb); int Nc=0,Nt=a[ta][0]+a[tb][0]; for(int i=1,j=1;i<=a[ta][0]&&j<=a[tb][0];) { if(a[ta][i]==a[tb][j]) { Nc++; i++; j++; continue; } if(a[ta][i]>a[tb][j])j++; else i++; } Nt-=Nc; double ans=((double)Nc)/((double)Nt)*100; printf("%.2lf%%\n",ans); } return 0; }

(推薦的網址: https://blog.csdn.net/qq_42475914/article/details/84311235 )
題解
二叉樹前序遍歷是先輸出當前遍歷節(jié)點,再按照左子樹右子樹順序遍歷
二叉樹中序遍歷是先遍歷左子樹,再輸出當前遍歷節(jié)點,再遍歷右子樹
二叉樹后序遍歷是先按照左子樹右子樹順序遍歷,再輸出當前遍歷節(jié)點
二叉樹層序遍歷是按照二叉樹的深度從左往右進行輸出
于是我們可知,后序遍歷序列的最后一個數字是根節(jié)點
我們就可以對照中序遍歷序列找出其左右子樹長度,按照長度再后序遍歷序列中找出其子樹的后序遍歷即可。
代碼

#include<iostream> #include<cstdio> using namespace std; int H[35],Z[35]; int ans[35][35]; void dfs(int H_l,int H_r,int Z_l,int Z_r,int cnt) { ans[cnt][0]++; ans[cnt][ans[cnt][0]]=H[H_r]; for(int i=Z_l;i<=Z_r;++i) { if(Z[i]==H[H_r]) { if(i-1>=Z_l)dfs(H_l,H_l+i-Z_l-1,Z_l,i-1,cnt+1); if(i+1<=Z_r)dfs(H_l+i-Z_l,H_r-1,i+1,Z_r,cnt+1); } } return; } int main() { int N; scanf("%d",&N); for(int i=1;i<=N;++i)scanf("%d",&H[i]); for(int i=1;i<=N;++i)scanf("%d",&Z[i]); dfs(1,N,1,N,1); for(int i=1;ans[i][0]!=0;++i) { for(int j=1;j<=ans[i][0];++j) { printf("%d",ans[i][j]); if(j!=ans[i][0]||ans[i+1][0]!=0)printf(" "); } } return 0; }

7-11 家庭房產

題解
使用并查集算法將不同人的信息進行合并,最后輸出信息即可
并查集
在計算機科學中,并查集是一種樹型的數據結構,用于處理一些不交集(Disjoint Sets)的合并及查詢
問題。
有一個聯合查找算法(union-find algorithm)定義了兩個用于此數據結構的操作:
·Find:確定元素屬于哪一個子集。這個確定方法就是不斷向上查找找到它的根節(jié)點,它可以被用來確
定兩個元素是否屬于同一子集。
·Union:將兩個子集合并成同一個集合。
(定義來自網絡,其實還有一個judge操作)
代碼

#include<iostream> #include<cstdio> #include<algorithm> using namespace std; struct PEO{ int id; int num_house,num_family,num_S; double PJ_house()const { return ((double)num_house)/((double)num_family); } double PJ_S()const { return ((double)num_S)/((double)num_family); } bool operator<(const PEO &b) const { if(PJ_S()!=b.PJ_S())return PJ_S()>b.PJ_S(); else return id<b.id; } }A[10000]; int Find(int x)//并查集 { if(A[x].id!=x)A[x].id=Find(A[x].id); return A[x].id; } void unioon(int x,int y) { x=Find(x); y=Find(y); if(x==y)return; if(x>y)swap(x,y); A[y].id=x; A[x].num_family+=A[y].num_family; A[x].num_house+=A[y].num_house; A[x].num_S+=A[y].num_S; A[y].num_S=-1; }

7-12 最長對稱子串

int main() { int N; scanf("%d",&N); for(int i=0;i<=9999;++i)//無論數據中有沒有,凡是提到了就算一口人 { A[i].id=i; A[i].num_family=1; A[i].num_house=0; A[i].num_S=0; } for(int i=1;i<=N;++i) { scanf("%d%d%d%d",&CZ[i][1],&CZ[i][2],&CZ[i][3],&CZ[i][4]); vis[CZ[i][1]]=true; if(CZ[i][2]!=-1)vis[CZ[i][2]]=true; if(CZ[i][3]!=-1)vis[CZ[i][3]]=true; for(int j=1;j<=CZ[i][4];++j) { scanf("%d",&CZ[i][4+j]); vis[CZ[i][4+j]]=true; } scanf("%d%d",&A[CZ[i][1]].num_house,&A[CZ[i][1]].num_S); } for(int i=1;i<=N;++i) { if(CZ[i][2]!=-1)unioon(CZ[i][1],CZ[i][2]); if(CZ[i][3]!=-1)unioon(CZ[i][1],CZ[i][3]); for(int j=1;j<=CZ[i][4];++j) { unioon(CZ[i][1],CZ[i][4+j]); } } sort(A,A+10000); int cnt=0; while(vis[A[cnt].id])cnt++;//判斷有幾戶人家 printf("%d\n",cnt); for(int i=0;i<cnt;++i) { printf("%04d %d %.3lf %.3lf\n",A[i].id,A[i].num_family,A[i].PJ_house(),A[i].PJ_S()); } return 0; }

題解
1.馬拉車算法(Manacher‘s Algorithm),時間復雜度為O(N)
2.本題解中代碼:使用動態(tài)規(guī)劃,時間復雜度為O(N^2)
定義:s[i,j]是字符串s由下標i到下標j的字符組成的字符串
dp[i,j]判斷s[i,j]是否是回文串
易知, dp[i,j]=true的條件是dp[i+1,j-1]=true且s[i]==s[j]
然后跑一個二重循環(huán),遞推就可以了,每個回文串的長度則是j-i+1
代碼

7-13 腫瘤診斷

題解
使用BFS求出每一個腫瘤的體積,再判斷是否超過閾值即可
不要使用dfs,會出現堆棧溢出的情況
代碼

#include<iostream> #include<cstdio> #include<cstring> using namespace std; char A[1005]; bool t[1005][1005]; int main() { int ans=1; int len=1; while((A[len]=getchar())!=EOF)len++; for(int i=1;i<=len;++i)t[i][1]=true; for(int i=1;i<len;++i)if(A[i]==A[i+1])t[i][2]=true; for(int i=3;i<=len;++i) { for(int j=1;j+i-1<=len;++j) { if(t[j+1][i-2]&&A[j]==A[j+i-1]) { t[j][i]=true; ans=i; } else t[j][i]=false; } } printf("%d",ans); return 0; }#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; bool vis[1287][129][61]; bool mpa[1287][129][61]; const int xx[6]={1,-1,0,0,0,0}; const int yy[6]={0,0,1,-1,0,0}; const int zz[6]={0,0,0,0,1,-1}; int M,N,L,T; struct point{ int x,y,z; }; int dfs(int x,int y,int z) { int res=0; vis[x][y][z]=true; point st; st.x=x; st.y=y; st.z=z; queue<point>q1; q1.push(st); while(!q1.empty()) { point w=q1.front(); q1.pop(); if(!mpa[w.x][w.y][w.z])continue; res++; for(int i=0;i<6;++i) { point tem=w; tem.x+=xx[i]; tem.y+=yy[i]; tem.z+=zz[i]; if(tem.x>=1&&tem.x<=M&&tem.y>=1&&tem.y<=N&&tem.z>=1&&tem.z<=L&&!vis[tem.x] [tem.y][tem.z]) { q1.push(tem); vis[tem.x][tem.y][tem.z]=true; } } } return res; } int main() { scanf("%d%d%d%d",&M,&N,&L,&T); for(int k=1;k<=L;++k) { for(int i=1;i<=M;++i) { for(int j=1;j<=N;++j) { int t; scanf("%d",&t); if(t)mpa[i][j][k]=true; else mpa[i][j][k]=false; } } } int ans=0; for(int k=1;k<=L;++k) { for(int i=1;i<=M;++i) { for(int j=1;j<=N;++j) { if(vis[i][j][k])continue; int tem=dfs(i,j,k); if(tem>=T)ans+=tem; } } } printf("%d",ans); return 0; }

7-14 垃圾箱分布

題解
Gx表示的垃圾桶編號可以看做1000+x的節(jié)點(技巧)
這個題需要使用最短路算法,請自行百度
(推薦的網站:https://blog.csdn.net/strve/article/details/80957491)
①所以垃圾箱的位置必須選在到所有居民點的最短距離最長的地方
②如果解不唯一,則輸出到所有居民點的平均距離最短的那個解
③如果這樣的解還是不唯一,則輸出編號最小的地點。
三句話決定排序關鍵字:
到居民樓最短距離最長的路徑長度(降序)
總路徑長度(升序)
編號(升序)
則序列的第一個符合到居民樓最短距離最長的路徑長度< Ds的即為答案
代碼

#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; struct Edge{ int n,v; long long w; }edge[20005]; int head[1050],num_edge; void add_edge(int u,int v,long long w) { num_edge++; edge[num_edge].n=head[u]; edge[num_edge].v=v; edge[num_edge].w=w; head[u]=num_edge; } long long dis[1050]; bool vis[1050]; long long ans[15][3];//0 is max dis,1 is min dis,2 is total dis int N,M,K; long long D; void SPFA(int u) { memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); queue<int>q1; q1.push(u); vis[u]=true; dis[u]=0; while(!q1.empty()) { int w=q1.front(); q1.pop(); vis[w]=false; for(int i=head[w];i;i=edge[i].n) { if(dis[edge[i].v]>dis[w]+edge[i].w) { dis[edge[i].v]=dis[w]+edge[i].w; if(!vis[edge[i].v]) { vis[edge[i].v]=true; q1.push(edge[i].v); } } } } for(int i=1;i<=N;++i) { if(dis[i]>ans[u-1000][0])ans[u-1000][0]=dis[i]; ans[u-1000][2]+=dis[i]; } ans[u-1000][1]=9223372036854775807LL; for(int i=1;i<=N;++i) { if(dis[i]<ans[u-1000][1])ans[u-1000][1]=dis[i]; } return; } int main() { scanf("%d%d%d%lld",&N,&M,&K,&D); for(int i=1;i<=K;++i) { char A[10]={0},B[10]={0}; int a=0,b=0; long long w; bool a_g=false,b_g=false; scanf("%s%s%lld",A,B,&w); int len=strlen(A); for(int j=0;j<len;++j) { if(A[j]=='G')a_g=true; else { a*=10; a+=A[j]-'0'; } } len=strlen(B); for(int j=0;j<len;++j) { if(B[j]=='G')b_g=true; else { b*=10; b+=B[j]-'0'; } } if(a_g)a+=1000; if(b_g)b+=1000; add_edge(a,b,w); add_edge(b,a,w); } for(int i=1;i<=M;++i) { SPFA(1000+i); } int ppd=-1; for(int i=1;i<=M;++i) { if(ans[i][0]>D)continue; if(ppd==-1) { ppd=i; continue; } if(ans[i][1]>ans[ppd][1])ppd=i; else if(ans[i][1]==ans[ppd][1]&&ans[i][2]<ans[ppd][2]) { ppd=i; } } if(ppd==-1) { printf("No Solution"); } else { printf("G%d\n",ppd); printf("%.1lf %.1lf",(double)ans[ppd][1],((double)ans[ppd] [2]/(double)N)); } return 0; }

7-15 迎風一刀斬

題解
簡單十分復雜的分類討論
1.看輸入的兩個多邊形端點數之和是否超過8或者是否有任意一個超過5,有則輸出NO
2.看多邊形與坐標軸平行的邊數是否為端點數-1,如果不等于,看是否為兩個矩形,若是兩個矩形,再
看這兩個矩形是否有邊長相等;有則輸出YES,除此之外邊數不等于端點數-1的情況均輸出NO
3.看多邊形是否為凸多邊形(可以凸包,也可以強行討論(不同討論方式情況不同,某種方式討論出十
二種情況每種還巨麻煩)(自認為最優(yōu)解是看多邊形的非直角,五邊形的需要2個鈍角,四邊形需要1鈍
1銳,通過向量求cos即可)不是則輸出NO)
4.如果兩塊殘片都是有1條斜邊的四邊形,除了要檢查兩條斜邊是否一致,還要檢查兩塊殘片內部的銳
角是否相等,如下圖。
5.計算斜邊斜率以及斜邊長度,如果長度相等,且斜邊平行/垂直或水平翻轉的其中一條斜邊與另一條平
行/垂直即為YES,否則為NO
這個題需要使用最短路算法,請自行百度
(推薦的網站:https://blog.csdn.net/strve/article/details/80957491)
①所以垃圾箱的位置必須選在到所有居民點的最短距離最長的地方
②如果解不唯一,則輸出到所有居民點的平均距離最短的那個解
③如果這樣的解還是不唯一,則輸出編號最小的地點。

三句話決定排序關鍵字:
到居民樓最短距離最長的路徑長度(降序)
總路徑長度(升序)
編號(升序)
【則序列的第一個符合到居民樓最短距離最長的路徑長度< Ds的即為答案】
(然后按照題目要求篩去不符合要求的答案即可)
代碼

#include<iostream> #include<cstdio> #include<cmath> using namespace std; int main() { int N; scanf("%d",&N); while(N--) { int a,b; int A[15][2]={0},B[15][2]={0}; scanf("%d",&a); for(int i=1;i<=a;++i)scanf("%d%d",&A[i][0],&A[i][1]); A[a+1][0]=A[1][0]; A[a+1][1]=A[1][1]; scanf("%d",&b); for(int i=1;i<=b;++i)scanf("%d%d",&B[i][0],&B[i][1]); B[b+1][0]=B[1][0]; B[b+1][1]=B[1][1]; if(a>5||b>5||a+b>8) { printf("NO\n"); continue; } //判斷直角數 int xa_id=0,xb_id=0; int cnta=0,cntb=0; for(int i=1;i<=a;++i) { if(A[i][0]==A[i+1][0]||A[i][1]==A[i+1][1])cnta++; else xa_id=i; } for(int i=1;i<=b;++i) { if(B[i][0]==B[i+1][0]||B[i][1]==B[i+1][1])cntb++; else xb_id=i; } if(cnta!=a-1||cntb!=b-1) { if(cnta==4&&cntb==4&&a==4&&b==4)//兩個矩形特判 { int len[3]; len[0]=max(A[1][0]>A[2][0]?A[1][0]-A[2][0]:A[2][0]-A[1][0],A[1] [1]>A[2][1]?A[1][1]-A[2][1]:A[2][1]-A[1][1]); len[1]=max(A[2][0]>A[3][0]?A[2][0]-A[3][0]:A[3][0]-A[2][0],A[2] [1]>A[3][1]?A[2][1]-A[3][1]:A[3][1]-A[2][1]); len[2]=max(B[1][0]>B[2][0]?B[1][0]-B[2][0]:B[2][0]-B[1][0],B[1] [1]>B[2][1]?B[1][1]-B[2][1]:B[2][1]-B[1][1]); if(len[0]==len[2]||len[1]==len[2]) { printf("YES\n"); continue; } } printf("NO\n"); continue; } if(a==5)//判斷是否為凸多邊形 { long long xa,xb,ya,yb,xc,xd,yc,yd; int t1=xa_id,t2=(xa_id)%a+1; xa=A[t1][0]-A[t1+1][0]; xb=A[t1][0]-A[(t1+3)%a+1][0]; ya=A[t1][1]-A[t1+1][1]; yb=A[t1][1]-A[(t1+3)%a+1][1]; xc=A[t2][0]-A[t2+1][0]; xd=A[t2][0]-A[(t2+3)%a+1][0]; yc=A[t2][1]-A[t2+1][1]; yd=A[t2][1]-A[(t2+3)%a+1][1]; if(xa*xb+ya*yb>=0||xc*xd+yc*yd>=0) { printf("NO\n"); continue; } } if(b==5)//判斷是否為凸多邊形 { long long xa,xb,ya,yb,xc,xd,yc,yd; int t1=xb_id,t2=(xb_id)%b+1; xa=B[t1][0]-B[t1+1][0]; xb=B[t1][0]-B[(t1+3)%b+1][0]; ya=B[t1][1]-B[t1+1][1]; yb=B[t1][1]-B[(t1+3)%b+1][1]; xc=B[t2][0]-B[t2+1][0]; xd=B[t2][0]-B[(t2+3)%b+1][0]; yc=B[t2][1]-B[t2+1][1]; yd=B[t2][1]-B[(t2+3)%b+1][1]; if(xa*xb+ya*yb>=0||xc*xd+yc*yd>=0) { printf("NO\n"); continue; } } if(a==4)//判斷是否為凸多邊形 { long long xa,xb,ya,yb,xc,xd,yc,yd; int t1=xa_id,t2=(xa_id)%a+1; xa=A[t1][0]-A[t1+1][0]; xb=A[t1][0]-A[(t1+2)%a+1][0]; ya=A[t1][1]-A[t1+1][1]; yb=A[t1][1]-A[(t1+2)%a+1][1]; xc=A[t2][0]-A[t2+1][0]; xd=A[t2][0]-A[(t2+2)%a+1][0]; yc=A[t2][1]-A[t2+1][1]; yd=A[t2][1]-A[(t2+2)%a+1][1]; if((xa*xb+ya*yb>=0&&xc*xd+yc*yd>=0)||(xa*xb+ya*yb<0&&xc*xd+yc*yd<0)) { printf("NO\n"); continue; } } if(b==4)//判斷是否為凸多邊形 { long long xa,xb,ya,yb,xc,xd,yc,yd; int t1=xb_id,t2=(xb_id)%b+1; xa=B[t1][0]-B[t1+1][0]; xb=B[t1][0]-B[(t1+2)%b+1][0]; ya=B[t1][1]-B[t1+1][1]; yb=B[t1][1]-B[(t1+2)%b+1][1]; xc=B[t2][0]-B[t2+1][0]; xd=B[t2][0]-B[(t2+2)%b+1][0]; yc=B[t2][1]-B[t2+1][1]; yd=B[t2][1]-B[(t2+2)%b+1][1]; if((xa*xb+ya*yb>=0&&xc*xd+yc*yd>=0)||(xa*xb+ya*yb<0&&xc*xd+yc*yd<0)) { printf("NO\n"); continue; } } long long len[7]; len[1]=(long long)(A[xa_id][0]-A[xa_id+1][0]); len[2]=(long long)(A[xa_id][1]-A[xa_id+1][1]); len[3]=len[1]*len[1]+len[2]*len[2]; len[4]=(long long)(B[xb_id][0]-B[xb_id+1][0]); len[5]=(long long)(B[xb_id][1]-B[xb_id+1][1]); len[6]=len[4]*len[4]+len[5]*len[5]; if(len[3]==len[6]&& (len[1]*len[5]==len[2]*len[4]||len[2]*len[5]==len[1]*len[4]||len[1]*len[4]+len[2 ]*len[5]==0||len[2]*len[4]+len[1]*len[5]==0))//判斷斜邊斜率 { if(a==4&&b==4)//判斷四邊形是否有兩個銳角相等 { long long xa,xb,ya,yb,xc,xd,yc,yd; long long Ax1,Ax2,Ay1,Ay2; int t1=xa_id,t2=(xa_id)%a+1; xa=A[t1][0]-A[t1+1][0]; xb=A[t1][0]-A[(t1+2)%a+1][0]; ya=A[t1][1]-A[t1+1][1]; yb=A[t1][1]-A[(t1+2)%a+1][1]; xc=A[t2][0]-A[t2+1][0]; xd=A[t2][0]-A[(t2+2)%a+1][0]; yc=A[t2][1]-A[t2+1][1]; yd=A[t2][1]-A[(t2+2)%a+1][1]; if(xa*xb+ya*yb>0) { Ax1=xa; Ax2=xb; Ay1=ya; Ay2=yb; } else { Ax1=xc; Ax2=xd; Ay1=yc; Ay2=yd; } long long xat,xbt,yat,ybt,xct,xdt,yct,ydt; long long Bx1,Bx2,By1,By2; int tt1=xb_id,tt2=(xb_id)%b+1; xat=B[tt1][0]-B[tt1+1][0]; xbt=B[tt1][0]-B[(tt1+2)%b+1][0]; yat=B[tt1][1]-B[tt1+1][1]; ybt=B[tt1][1]-B[(tt1+2)%b+1][1]; xct=B[tt2][0]-B[tt2+1][0]; xdt=B[tt2][0]-B[(tt2+2)%b+1][0]; yct=B[tt2][1]-B[tt2+1][1]; ydt=B[tt2][1]-B[(tt2+2)%b+1][1]; if(xat*xbt+yat*ybt>0) { Bx1=xat; Bx2=xbt; By1=yat; By2=ybt; } else { Bx1=xct; Bx2=xdt; By1=yct; By2=ydt; } if((Ax1*Ax2+Ay1*Ay2)*(Ax1*Ax2+Ay1*Ay2)*(Bx1*Bx1+By1*By1)* (Bx2*Bx2+By2*By2)!=(Bx1*Bx2+By1*By2)*(Bx1*Bx2+By1*By2)*(Ax1*Ax1+Ay1*Ay1)* (Ax2*Ax2+Ay2*Ay2)) { printf("NO\n"); continue; } } printf("YES\n"); continue; } printf("NO\n"); } return 0; }

總結

以上是生活随笔為你收集整理的东北大学第二场算法题解报告的全部內容,希望文章能夠幫你解決所遇到的問題。

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