2018天梯賽第二次選拔賽


7-1 計算物體自由下落的距離(5 分)

一個物體從100米的高空自由落下。編寫程序,求它在前3秒內下落的垂直距離。設重力加速度為10米/秒2​​。

輸入格式:

本題目沒有輸入。

輸出格式:

按照下列格式輸出

height = 垂直距離值

結果保留2位小數。

H=1/2*g*t2

1 #include<bits/stdc++.h>
2 using namespace std;
3 int main()
4 {
5     printf("height = 45.00");
6     return 0;
7 }

7-2 有理數比較(10 分)

本題要求編寫程序,比較兩個有理數的大小。

輸入格式:

輸入在一行中按照“a1/b1 a2/b2”的格式給出兩個分數形式的有理數,其中分子和分母全是整形范圍內的正整數。

輸出格式:

在一行中按照“a1/b1 關系符 a2/b2”的格式輸出兩個有理數的關系。其中“>”表示“大於”,“<”表示“小於”,“=”表示“等於”。

輸入樣例1:

1/2 3/4

輸出樣例1:

1/2 < 3/4

輸入樣例2:

6/8 3/4

輸出樣例2:

6/8 = 3/4
#include<bits/stdc++.h>
using namespace std;
int main()
{
    double a,b,c,d;
    scanf("%lf/%lf %lf/%lf",&a,&b,&c,&d);
    printf("%.0f/%.0f",a,b);
    if(a/b<c/d)printf(" < ");
    else if(a/b>c/d)printf(" > ");
    else printf(" = ");
    printf("%.0f/%.0f",c,d);
    return 0;
}

7-3 宇宙無敵大招呼(5 分)

據說所有程序員學習的第一個程序都是在屏幕上輸出一句“Hello World”,跟這個世界打個招呼。作為天梯賽中的程序員,你寫的程序得高級一點,要能跟任意指定的星球打招呼。

輸入格式:

輸入在第一行給出一個星球的名字S,是一個由不超過7個英文字母組成的單詞,以回車結束。

輸出格式:

在一行中輸出Hello S,跟輸入的S星球打個招呼。

輸入樣例:

Mars

輸出樣例:

Hello Mars
1 #include<bits/stdc++.h>
2 using namespace std;
3 int main()
4 {
5     string s;
6     cin>>s;
7     cout<<"Hello "<<s;
8     return 0;
9 }

7-4 字符串替換(15 分)

本題要求編寫程序,將給定字符串中的大寫英文字母按以下對應規則替換:

原字母 對應字母
A Z
B Y
C X
D W
X C
Y B
Z A

輸入格式:

輸入在一行中給出一個不超過80個字符、並以回車結束的字符串。

輸出格式:

輸出在一行中給出替換完成后的字符串。

輸入樣例:

Only the 11 CAPItaL LeTtERS are replaced.

輸出樣例:

Lnly the 11 XZKRtaO OeGtVIH are replaced.
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     string a,s="ZYXWVUTSRQPONMLKJIHGFEDCBA";
 6     getline(cin,a);
 7     for(int i=0;a[i];i++)
 8         if(a[i]>='A'&&a[i]<='Z')
 9             printf("%c",s[a[i]-'A']);
10         else
11             printf("%c",a[i]);
12     return 0;
13 }

7-5 點贊(20 分)

微博上有個“點贊”功能,你可以為你喜歡的博文點個贊表示支持。每篇博文都有一些刻畫其特性的標簽,而你點贊的博文的類型,也間接刻畫了你的特性。本題就要求你寫個程序,通過統計一個人點贊的紀錄,分析這個人的特性。

輸入格式:

輸入在第一行給出一個正整數N(1000),是該用戶點贊的博文數量。隨后N行,每行給出一篇被其點贊的博文的特性描述,格式為"K F1 F2 .....Fk",其中1K10,Fi(i=1,....,K)是特性標簽的編號,我們將所有特性標簽從1到1000編號。數字間以空格分隔。

輸出格式:

統計所有被點贊的博文中最常出現的那個特性標簽,在一行中輸出它的編號和出現次數,數字間隔1個空格。如果有並列,則輸出編號最大的那個。

輸入樣例:

4
3 889 233 2
5 100 3 233 2 73
4 3 73 889 2
2 233 123

輸出樣例:

233 3
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     int a,n,k,maxx=0,c;
 6     map<int,int> ma;
 7     cin>>n;
 8     for(int i=0;i<n;i++)
 9     {
10         cin>>k;
11         for(int j=0;j<k;j++)
12         {
13             cin>>a;
14             ma[a]++;
15             if(ma[a]>maxx||ma[a]==maxx&&a>c)
16             {
17                 maxx=ma[a];
18                 c=a;
19             }
20         }
21     }
22     cout<<c<<' '<<maxx;
23     return 0;
24 }

7-6 比較大小(10 分)

本題要求將輸入的任意3個整數從小到大輸出。

輸入格式:

輸入在一行中給出3個整數,其間以空格分隔。

輸出格式:

在一行中將3個整數從小到大輸出,其間以“->”相連。

輸入樣例:

4 2 8

輸出樣例:

2->4->8
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     int a[5];
 6     cin>>a[0]>>a[1]>>a[2];
 7     sort(a,a+3);
 8     printf("%d->%d->%d",a[0],a[1],a[2]);
 9     return 0;
10 }

7-7 求e的近似值(15 分)

自然常數e可以用級數1+1/1!+1/2!++1/n!來近似計算。本題要求對給定的非負整數n,求該級數的前n項和。

輸入格式:

輸入第一行中給出非負整數n(1000)。

輸出格式:

在一行中輸出部分和的值,保留小數點后八位。

輸入樣例:

10

輸出樣例:

2.71828180

其實先暴力輸出一下看看,后面都不變了

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     int n;
 6     cin>>n;
 7     double a=1,b=1;
 8     for(int i=1;i<=n&&i<=11;i++)
 9     {
10         b*=i;
11         a+=1/b;
12     }
13     printf("%.8f",a);
14     return 0;
15 }

7-8 數組循環左移(20 分)

本題要求實現一個對數組進行循環左移的簡單函數:一個數組a中存有n(>0)個整數,在不允許使用另外數組的前提下,將每個整數循環向左移m(≥0)個整數,在不允許使用另外數組的前提下,將每個整數循環向左移m(≥0)個位置,即將a中的數據由(a0a1a2...an-1)變換為(am....an-1a0a1....am-1)(最前面的m個數循環移至最后面的m個位置)。如果還需要考慮程序移動數據的次數盡量少,要如何設計移動的方法?

輸入格式:

輸入第1行給出正整數n(≤100)和整數m(≥0);第2行給出n個整數,其間以空格分隔。

輸出格式:

在一行中輸出循環左移m位以后的整數序列,之間用空格分隔,序列結尾不能有多余空格。

輸入樣例:

8 3
1 2 3 4 5 6 7 8

輸出樣例:

4 5 6 7 8 1 2 3

模擬一下,找找規律

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     int n,m,a[105];
 6     vector<int> v;
 7     cin>>n>>m;
 8     for(int i=0;i<n;i++)
 9         cin>>a[i];
10     int p=m%n;
11     for(int i=p;i<n;i++)
12         v.push_back(a[i]);
13     for(int i=0;i<p;i++)
14         v.push_back(a[i]);
15     for(int i=0;i<n;i++)
16         printf("%d%c",v[i],i==n-1?'\n':' ');
17     return 0;
18 }

7-9 列出連通集(25 分)

給定一個有N個頂點和E條邊的無向圖,請用DFS和BFS分別列出其所有的連通集。假設頂點從0到N1編號。進行搜索時,假設我們總是從編號最小的頂點出發,按編號遞增的順序訪問鄰接點。

輸入格式:

輸入第1行給出2個整數N(0<N≤10)E,分別是圖的頂點數和邊數。隨后E行,每行給出一條邊的兩個端點。每行中的數字之間用1空格分隔。

輸出格式:

按照"{v1v2v3.....vk}"的格式,每行輸出一個連通集。先輸出DFS的結果,再輸出BFS的結果。

輸入樣例:

8 6
0 7
0 1
2 0
4 1
2 4
3 5

輸出樣例:

{ 0 1 4 2 7 }
{ 3 5 }
{ 6 }
{ 0 1 2 7 4 }
{ 3 5 }
{ 6 }

深搜DFS,廣搜DFS基本操作

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int Vis[20],G[20][20],n,m;
 4 void dfs(int u)
 5 {
 6     printf(" %d",u);
 7     for(int i=0;i<n;i++)
 8     {
 9         if(!Vis[i]&&G[u][i])
10         {
11             Vis[i]=1;
12             dfs(i);
13         }
14     }
15 }
16 void bfs(int s)
17 {
18     queue<int> Q;
19     Q.push(s);
20     while(!Q.empty())
21     {
22         int u=Q.front();Q.pop();
23         printf(" %d",u);
24         for(int i=0;i<n;i++)
25         {
26             if(!Vis[i]&&G[u][i])
27             {
28                 Vis[i]=1;
29                 Q.push(i);
30             }
31         }
32     }
33 }
34 int main()
35 {
36     int u,v;
37     cin>>n>>m;
38     for(int i=0;i<m;i++)
39     {
40         cin>>u>>v;
41         G[u][v]=G[v][u]=1;
42     }
43     memset(Vis,0,sizeof(Vis));
44     for(int i=0;i<n;i++)
45     {
46         if(!Vis[i])
47         {
48             Vis[i]=1;
49             printf("{");
50             dfs(i);
51             printf(" }\n");
52         }
53     }
54     memset(Vis,0,sizeof(Vis));
55     for(int i=0;i<n;i++)
56     {
57         if(!Vis[i])
58         {
59             Vis[i]=1;
60             printf("{");
61             bfs(i);
62             printf(" }\n");
63         }
64     }
65     return 0;
66 }

7-10 文件傳輸(25 分)

當兩台計算機雙向連通的時候,文件是可以在兩台機器間傳輸的。給定一套計算機網絡,請你判斷任意兩台指定的計算機之間能否傳輸文件?

輸入格式:

首先在第一行給出網絡中計算機的總數 N (2N104​​),於是我們假設這些計算機從 1 到 N 編號。隨后每行輸入按以下格式給出:

I c1 c2

其中I表示在計算機c1c2之間加入連線,使它們連通;或者是

C c1 c2

其中C表示查詢計算機c1c2之間能否傳輸文件;又或者是

S

這里S表示輸入終止。

輸出格式:

對每個C開頭的查詢,如果c1c2之間可以傳輸文件,就在一行中輸出"yes",否則輸出"no"。當讀到終止符時,在一行中輸出"The network is connected."如果網絡中所有計算機之間都能傳輸文件;或者輸出"There are k components.",其中k是網絡中連通集的個數。

輸入樣例 1:

5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
S

輸出樣例 1:

no
no
yes
There are 2 components.

輸入樣例 2:

5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
I 1 3
C 1 5
S

輸出樣例 2:

no
no
yes
yes
The network is connected.

並查集基本操作

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e4+5;
 4 int F[N];
 5 int Find(int x)
 6 {
 7     return F[x]==x?x:F[x]=Find(F[x]);
 8 }
 9 void Join(int a,int b)
10 {
11     int fx=Find(a);
12     int fy=Find(b);
13     if(fx!=fy)
14         F[fx]=fy;
15 }
16 void init(int n)
17 {
18     for(int i=1;i<=n;i++)F[i]=i;
19 }
20 int main()
21 {
22     int n,u,v;
23     string s;
24     cin>>n;
25     init(n);
26     while(1)
27     {
28         cin>>s;
29         if(s=="S")break;
30         cin>>u>>v;
31         if(s=="I")Join(u,v);
32         else
33         {
34             if(Find(u)==Find(v))cout<<"yes\n";
35             else cout<<"no\n";
36         }
37     }
38     int cnt=0;
39     for(int i=1;i<=n;i++)
40         if(F[i]==i)
41             cnt++;
42     if(cnt==1)printf("The network is connected.\n");
43     else printf("There are %d components.\n",cnt);
44     return 0;
45 }

7-11 重排鏈表(25 分)

給定一個單鏈表 L1→L2→...→Ln-1→Ln,請編寫程序將鏈表重新排列為 Ln→L1→Ln-1→L2→...。例如:給定L為1→2→3→4→5→6,則輸出應該為6→1→5→2→4→3。

輸入格式:

每個輸入包含1個測試用例。每個測試用例第1行給出第1個結點的地址和結點總個數,即正整數N(≤105)。結點的地址是5位非負整數,NULL地址用1表示。

接下來有N行,每行格式為:

Address Data Next

其中Address是結點地址;Data是該結點保存的數據,為不超過105​​的正整數;Next是下一結點的地址。題目保證給出的鏈表上至少有兩個結點。

輸出格式:

對每個測試用例,順序輸出重排后的結果鏈表,其上每個結點占一行,格式與輸入相同。

輸入樣例:

00100 6
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

輸出樣例:

68237 6 00100
00100 1 99999
99999 5 12309
12309 2 00000
00000 4 33218
33218 3 -1

這個題一直22分,后來發現有多余結點的情況,結點<=k,如果循環0-k的話就超時了,詳細看代碼

給個樣例

1 3

1 0 2

2 0 -1

3 0 4

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=100000+5;
 4 struct Node
 5 {
 6     int u,next,w;
 7 }A[N];
 8 vector<Node> v;
 9 int main()
10 {
11     int s,k,u,next,w;
12     cin>>s>>k;
13     for(int i=0;i<k;i++)
14     {
15         cin>>u>>w>>next;
16         A[u].u=u;
17         A[u].next=next;
18         A[u].w=w;
19     }
20     int cnt=0;//所有有效的結點數<=k(可能有無效結點)
21     //for(int i=0;i<k;i++)這樣寫就過不去了
22     while(1)
23     {
24         v.push_back(A[s]);
25         cnt++;
26         s=A[s].next;
27         if(s==-1)break;
28     }
29     int i=0,j=cnt-1;
30     while(1)
31     {
32         //輸出最后1個和第1個
33         printf("%05d %d %05d\n",v[j].u,v[j].w,v[i].u);
34         printf("%05d %d ",v[i].u,v[i].w);
35         i++;j--;
36         if(i!=j)
37         {
38             if(i<cnt/2)
39                 printf("%05d\n",v[j].u);
40             else//偶數結點的最后輸出
41             {
42                 printf("-1\n");
43                 break;
44             }
45         }
46         else//奇數結點的最后輸出
47         {
48             printf("%05d\n%05d %d -1\n",v[j].u,v[j].u,v[j].w);
49             break;
50         }
51     }
52     return 0;
53 }

7-12 人以群分(25 分)

社交網絡中我們給每個人定義了一個“活躍度”,現希望根據這個指標把人群分為兩大類,即外向型(outgoing,即活躍度高的)和內向型(introverted,即活躍度低的)。要求兩類人群的規模盡可能接近,而他們的總活躍度差距盡可能拉開。

輸入格式:

輸入第一行給出一個正整數N(2≤N≤105。隨后一行給出N個正整數,分別是每個人的活躍度,其間以空格分隔。題目保證這些數字以及它們的和都不會超過231

輸出格式:

按下列格式輸出:

Outgoing #: N1
Introverted #: N2
Diff = N3

其中N1是外向型人的個數;N2是內向型人的個數;N3是兩群人總活躍度之差的絕對值。

輸入樣例1:

10
23 8 10 99 46 2333 46 1 666 555

輸出樣例1:

Outgoing #: 5
Introverted #: 5
Diff = 3611

輸入樣例2:

13
110 79 218 69 3721 100 29 135 2 6 13 5188 85

輸出樣例2:

Outgoing #: 7
Introverted #: 6
Diff = 9359
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     int n,n1=0,n2=0,a[100005];
 6     scanf("%d",&n);
 7     for(int i=0;i<n;i++)
 8         scanf("%d",&a[i]);
 9     sort(a,a+n);
10     printf("Outgoing #: %d\n",n%2==0?n/2:n/2+1);
11     printf("Introverted #: %d\n",n/2);
12     for(int i=0;i<n/2;i++)
13         n1+=a[i];
14     for(int i=n/2;i<n;i++)
15         n2+=a[i];
16     printf("Diff = %d\n",n2-n1);
17     return 0;
18 }

7-13 關鍵活動(30 分)

假定一個工程項目由一組子任務構成,子任務之間有的可以並行執行,有的必須在完成了其它一些子任務后才能執行。“任務調度”包括一組子任務、以及每個子任務可以執行所依賴的子任務集。

比如完成一個專業的所有課程學習和畢業設計可以看成一個本科生要完成的一項工程,各門課程可以看成是子任務。有些課程可以同時開設,比如英語和C程序設計,它們沒有必須先修哪門的約束;有些課程則不可以同時開設,因為它們有先后的依賴關系,比如C程序設計和數據結構兩門課,必須先學習前者。

但是需要注意的是,對一組子任務,並不是任意的任務調度都是一個可行的方案。比如方案中存在“子任務A依賴於子任務B,子任務B依賴於子任務C,子任務C又依賴於子任務A”,那么這三個任務哪個都不能先執行,這就是一個不可行的方案。

任務調度問題中,如果還給出了完成每個子任務需要的時間,則我們可以算出完成整個工程需要的最短時間。在這些子任務中,有些任務即使推遲幾天完成,也不會影響全局的工期;但是有些任務必須准時完成,否則整個項目的工期就要因此延誤,這種任務就叫“關鍵活動”。

請編寫程序判定一個給定的工程項目的任務調度是否可行;如果該調度方案可行,則計算完成整個工程項目需要的最短時間,並輸出所有的關鍵活動。

輸入格式:

輸入第1行給出兩個正整數N(100)和M,其中N是任務交接點(即銜接相互依賴的兩個子任務的節點,例如:若任務2要在任務1完成后才開始,則兩任務之間必有一個交接點)的數量。交接點按1~N編號,M是子任務的數量,依次編號為1~M。隨后M行,每行給出了3個正整數,分別是該任務開始和完成涉及的交接點編號以及該任務所需的時間,整數間用空格分隔。

輸出格式:

如果任務調度不可行,則輸出0;否則第1行輸出完成整個工程項目需要的時間,第2行開始輸出所有關鍵活動,每個關鍵活動占一行,按格式“V->W”輸出,其中V和W為該任務開始和完成涉及的交接點編號。關鍵活動輸出的順序規則是:任務開始的交接點編號小者優先,起點編號相同時,與輸入時任務的順序相反。

輸入樣例:

7 8
1 2 4
1 3 3
2 4 5
3 4 3
4 5 1
4 6 6
5 7 5
6 7 2

輸出樣例:

17
1->2
2->4
4->6
6->7

題目好長看了半天沒理解意思,猜個0得了5分,看輸出像是拓撲排序題,沒時間就沒寫了

7-14 詞頻統計(30 分)

請編寫程序,對一段英文文本,統計其中所有不同單詞的個數,以及詞頻最大的前10%的單詞。

所謂“單詞”,是指由不超過80個單詞字符組成的連續字符串,但長度超過15的單詞將只截取保留前15個單詞字符。而合法的“單詞字符”為大小寫字母、數字和下划線,其它字符均認為是單詞分隔符。

輸入格式:

輸入給出一段非空文本,最后以符號#結尾。輸入保證存在至少10個不同的單詞。

輸出格式:

在第一行中輸出文本中所有不同單詞的個數。注意“單詞”不區分英文大小寫,例如“PAT”和“pat”被認為是同一個單詞。

隨后按照詞頻遞減的順序,按照詞頻:單詞的格式輸出詞頻最大的前10%的單詞。若有並列,則按遞增字典序輸出。

輸入樣例:

This is a test.

The word "this" is the word with the highest frequency.

Longlonglonglongword should be cut off, so is considered as the same as longlonglonglonee.  But this_8 is different than this, and this, and this...#
this line should be ignored.

輸出樣例:(注意:雖然單詞the也出現了4次,但因為我們只要輸出前10%(即23個單詞中的前2個)單詞,而按照字母序,the排第3位,所以不輸出。)

23
5:this
4:is

感謝武漢理工大學的郭小兵老師修正測試數據!

模擬題,一次讀入1個字母判斷,最后放入vector里排序即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define psi pair<string,int>
 4 bool cmp(psi a,psi b)
 5 {
 6     return a.second>b.second||a.second==b.second&&a.first<b.first;
 7 }
 8 int main()
 9 {
10     char ch;
11     string s;
12     map<string,int> ma;
13     for(;;)
14     {
15         ch=getchar();
16         if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')||(ch=='_'))
17         {
18             if(s.size()<=14)
19             {
20                 if(ch>='A'&&ch<='Z')
21                     ch+=32;
22                 s+=ch;
23             }
24         }
25         else
26         {
27             if(s.size()>0)
28                 ma[s]++;
29             s.clear();
30         }
31         if(ch=='#')break;
32     }
33     vector<psi> v(ma.begin(),ma.end());
34     sort(v.begin(),v.end(),cmp);
35     cout<<v.size()<<endl;
36     int cnt=(int)(ma.size()*0.1);
37     for(int i=0;i<cnt;i++)
38         cout<<v[i].second<<':'<<v[i].first<<endl;
39     return 0;
40 }

7-15 二叉搜索樹的結構(30 分)

二叉搜索樹或者是一棵空樹,或者是具有下列性質的二叉樹: 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;它的左、右子樹也分別為二叉搜索樹。(摘自百度百科)

給定一系列互不相等的整數,將它們順次插入一棵初始為空的二叉搜索樹,然后對結果樹的結構進行描述。你需要能判斷給定的描述是否正確。例如將{ 2 4 1 3 0 }插入后,得到一棵二叉搜索樹,則陳述句如“2是樹的根”、“1和4是兄弟結點”、“3和0在同一層上”(指自頂向下的深度相同)、“2是4的雙親結點”、“3是4的左孩子”都是正確的;而“4是2的左孩子”、“1和3是兄弟結點”都是不正確的。

輸入格式:

輸入在第一行給出一個正整數N(≤100),隨后一行給出N個互不相同的整數,數字間以空格分隔,要求將之順次插入一棵初始為空的二叉搜索樹。之后給出一個正整數M(≤100),隨后M行,每行給出一句待判斷的陳述句。陳述句有以下6種:

  • A and B are siblings,即"AB是兄弟結點";
  • A is the parent of B,即"AB的雙親結點";
  • A is the left child of B,即"AB的左孩子";
  • A is the right child of B,即"AB的右孩子";
  • A and B are on the same level,即"AB在同一層上"。

題目保證所有給定的整數都在整型范圍內。

輸出格式:

對每句陳述,如果正確則輸出Yes,否則輸出No,每句占一行。

輸入樣例:

5
2 4 1 3 0
8
2 is the root
1 and 4 are siblings
3 and 0 are on the same level
2 is the parent of 4
3 is the left child of 4
1 is the right child of 2
4 and 0 are on the same level
100 is the right child of 3

輸出樣例:

Yes
Yes
Yes
Yes
Yes
No
No
No

一個二叉搜索樹題,得用鏈表,開數組內存吃不消,最大100層

建完樹,6種情況判斷一下即可,思路很清晰,注意仔細,詳細看代碼

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 struct Node
  4 {
  5     int data;
  6     Node *Left,*Right;
  7     Node():data(-1),Left(NULL),Right(NULL){}
  8 };
  9 Node *addnode(){return new Node();}//開結點
 10 Node *root,*FI;
 11 int flag;//用來標記是否繼續遞歸,1表示找到
 12 void Create(Node *u,int a)//建立二叉搜索樹
 13 {
 14     if(u->data==-1)
 15     {
 16         u->data=a;
 17         return ;
 18     }
 19     else
 20     {
 21         if(a>u->data)
 22         {
 23             if(u->Right==NULL)
 24                 u->Right=addnode();
 25             Create(u->Right,a);
 26         }
 27         else
 28         {
 29             if(u->Left==NULL)
 30                 u->Left=addnode();
 31             Create(u->Left,a);
 32         }
 33     }
 34 }
 35 void Find(Node *u,int a)
 36 {
 37     if(u->data==a)
 38     {
 39         flag=1;
 40         FI=u;
 41         return;
 42     }
 43     if(flag==0)
 44     {
 45         if(u->Left!=NULL)
 46             Find(u->Left,a);
 47         if(u->Right!=NULL)
 48             Find(u->Right,a);
 49     }
 50 }
 51 void FFF(Node *u,int a,int b)
 52 {
 53     if(u->Left!=NULL&&u->Right!=NULL)
 54     {
 55         if(u->Left->data==a&&u->Right->data==b)flag=1;
 56         if(u->Right->data==a&&u->Left->data==b)flag=1;
 57     }
 58     if(flag==0)
 59     {
 60         if(u->Left!=NULL)
 61             FFF(u->Left,a,b);
 62         if(u->Right!=NULL)
 63             FFF(u->Right,a,b);
 64     }
 65 }
 66 void Level(Node *u,int a,int k)
 67 {
 68     if(u->data==a)
 69     {
 70         flag=k;
 71         return;
 72     }
 73     if(flag==0)
 74     {
 75         if(u->Left!=NULL)
 76             Level(u->Left,a,k+1);
 77         if(u->Right!=NULL)
 78             Level(u->Right,a,k+1);
 79     }
 80 }
 81 int main()
 82 {
 83     root=addnode();
 84     int n,m,A,B,a;
 85     cin>>n;
 86     for(int i=0;i<n;i++)
 87     {
 88         cin>>a;
 89         Create(root,a);
 90     }
 91     cin>>m;
 92     string s;
 93     for(int i=0;i<m;i++)
 94     {
 95         int f=0;
 96         cin>>A>>s;
 97         if(s=="is")
 98         {
 99             cin>>s>>s;
100             if(s=="root")//1.A是樹的根
101             {
102                 if(root->data==A)
103                     f=1;
104             }
105             else if(s=="parent")//3.A是B的父母
106             {
107                 cin>>s>>B;
108                 flag=0;
109                 FI=NULL;
110                 Find(root,A);
111                 Node *u=FI;
112                 if(u!=NULL)//A存在
113                 {
114                     //A左右兒子存在且==B
115                     if(u->Left!=NULL&&u->Left->data==B)f=1;
116                     if(u->Right!=NULL&&u->Right->data==B)f=1;
117                 }
118             }
119             else if(s=="left")//4.A是B的左孩子
120             {
121                 cin>>s>>s>>B;
122                 FI=NULL;
123                 flag=0;
124                 Find(root,B);
125                 Node *u=FI;
126                 if(u!=NULL)//B存在
127                 {
128                     //B左兒子存在且==A
129                     if(u->Left!=NULL&&u->Left->data==A)f=1;
130                 }
131             }
132             else if(s=="right")//5.A是B的右孩子
133             {
134                 cin>>s>>s>>B;
135                 flag=0;
136                 FI=NULL;
137                 Find(root,B);
138                 Node *u=FI;
139                 if(u!=NULL)//B存在
140                 {
141                     //B左兒子存在且==A
142                     if(u->Right!=NULL&&u->Right->data==A)f=1;
143                 }
144             }
145         }
146         else if(s=="and")
147         {
148             cin>>B>>s>>s;
149             if(s=="siblings")//2.A和B是兄弟結點
150             {
151                 flag=0;
152                 FFF(root,A,B);
153                 if(flag)f=1;
154             }
155             else//6.A和B在同一層上
156             {
157                 cin>>s>>s>>s;
158                 flag=0;
159                 Level(root,A,1);
160                 int f1=flag;
161                 flag=0;
162                 Level(root,B,1);
163                 int f2=flag;
164                 //結點存在且層數相等
165                 if(f1>0&&f2>0&&f1==f2)f=1;
166             }
167         }
168         printf("%s\n",f?"Yes":"No");
169     }
170     return 0;
171 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM