Contest1088 - 2020年春季ACM集訓隊熱身賽-第2場
比賽原地址: 傳送門
問題 A: 河畔軍訓
題目描述
河畔鎮是一個景色秀麗,氣候宜人的度假勝地,每天都會有很多的遊客來這裏遊玩。但奇怪的是這裏總會出現一些潛伏者。果不其然,通過保衛者的跟蹤,發現在河畔鎮的地下隱藏着Blitz的祕密武器實驗室。最危險的地方也是最安全的地方,這裏人多,所以只能採用狙擊作戰,一場“無聲無息“的戰鬥即刻打響。
每到週末小z,小y便開始在河畔軍訓小h(當然有時也會被反軍訓)。
不過他們軍訓採用刀戰(即相遇時纔可軍訓)
每當小z,小y,小h三人在河畔整相遇時,小z和小y便可軍訓小h
由於小h有兔耳朵buff加成,小h每秒最多可以移動3步,且可以選擇上/下/左/右/左上/左下/右上/右下8個方向移動
小z,小y每秒均只能移動1步,只能上/下/左/右4個方向移動。
當然,三人均可選擇保持原地不動。
三人移動始終在地圖範圍內。
下面,給你河畔的地圖以及小z,小y,小h的初始座標。
請你求出最快軍訓小h的時間(即3人相遇的最短時間),如果無法軍訓小h則輸出“lack of junxun”
輸入
多組數據
每組數據第一行兩個整數N,M(1<=N,M<=1000)代表河畔地圖的行和列
接下來是N*M大小的地圖
其中“z”,“y”,“h”分別代表小z,小y,小h的初始座標
“#”代表障礙物,“.”表示可以正常通過的位置
輸出
對於每組數據
如果能軍訓小h,則輸出最快軍訓小h所需的時間
否則,輸出“lack of junxun”
樣例輸入
2 4
z…h
#y#.
2 3
z#y
#h.
樣例輸出
1
lack of junxun
解題思路
分別從三個起點開始用BFS,考慮題目的特殊性:
- z和y不能走斜線,只有小h能走
- 小h每秒最多可以移動3步
- 輸出最快軍訓小h所需的時間,那麼就貪心一下,讓小h每次都走最多步數:3步
參考博文:傳送門
AC代碼
#include<bits/stdc++.h>
#define endl '\n'
#define mst(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=1e3+5;
int n,m;
int vis[3][maxn][maxn];
char mp[maxn][maxn];
int dir[8][2]={0,1,1,0,0,-1,-1,0,1,1,1,-1,-1,-1,-1,1};
struct node{
int x,y;
};
bool check(int x,int y,int id){ //check函數判斷該點是否能走
if(x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]!='#'&&!vis[id][x][y]) return true;
return false;
}
queue<node> Q[3];
bool bfs(int u){
int cnt=Q[u].size();
node now,nex;
while(cnt--){
now=Q[u].front(),Q[u].pop();
for(int i=0;i<8;i++){
if(i>=4&&(u==0||u==1)) break; //z和y不能走斜線,只有h能走斜線
nex.x=now.x+dir[i][0];
nex.y=now.y+dir[i][1];
if(check(nex.x,nex.y,u)){
vis[u][nex.x][nex.y]=1;
Q[u].push(nex);
if(vis[0][nex.x][nex.y]&&vis[1][nex.x][nex.y]&&vis[2][nex.x][nex.y])
return true;
}
}
}
return false;
}
int solve(){
int step=0;
while(!Q[0].empty()||!Q[1].empty()||!Q[2].empty()){
++step;
if(bfs(0)) return step;
if(bfs(1)) return step;
for(int i=1;i<=3;i++)
if(bfs(2)) return step;
}
return -1;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
while(cin>>n>>m){
mst(vis,0);
while(!Q[0].empty()) Q[0].pop();
while(!Q[1].empty()) Q[1].pop();
while(!Q[2].empty()) Q[2].pop();
for(int i=1;i<=n;i++) cin>>mp[i]+1;
node now;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(mp[i][j]=='z'){
now.x=i,now.y=j;
vis[0][i][j]=1;
Q[0].push(now);
}else if(mp[i][j]=='y'){
now.x=i,now.y=j;
vis[1][i][j]=1;
Q[1].push(now);
}else if(mp[i][j]=='h'){
now.x=i,now.y=j;
vis[2][i][j]=1;
Q[2].push(now);
}
}
}
int ans=solve();
if(ans==-1)
cout<<"lack of junxun"<<endl;
else
cout<<ans<<endl;
}
return 0;
}
問題 B: 不高興的津津
題目描述
津津上初中了。媽媽認爲津津應該更加用功學習,所以津津除了上學之外,還要參加媽媽爲她報名的各科複習班。另外每週媽媽還會送她去學習朗誦、舞蹈和鋼琴。但是津津如果一天上課超過八個小時就會不高興,而且上得越久就會越不高興。假設津津不會因爲其它事不高興,並且她的不高興不會持續到第二天。請你幫忙檢查一下津津下週的日程安排,看看下週她會不會不高興;如果會的話,哪天最不高興。
輸入
輸入包括七行數據,分別表示週一到週日的日程安排。每行包括兩個小於10的非負整數,分別表示津津在學校上課的時間和媽媽安排她上課的時間。
輸出
輸出包括一行,這一行只包含一個數字。如果不會不高興那麼輸出0,如果會那麼輸出最不高興的是周幾〔用1,2,3,4,5,6,7分別表示週一,週二,週三,週四,週五,週六,週日〕。如果有兩天或兩天以上不高興的程度相當,那麼輸出時間最靠前的一天。
樣例輸入
53
62
72
53
54
04
06
樣例輸出
3
解題思路
輸出最不高興的天數,注意輸入的特殊性,中間沒有空格,因此需要進行字符串處理,判斷最大值時取大於號>即可
AC代碼
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int maxn=1e5+5;
int n,m;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int idx=0,tmp=0;
for(int i=1;i<=7;i++){
char s[5];
cin>>s;
n=s[0]-'0';
m=s[1]-'0';
int sum=n+m;
if(sum>8&&sum>tmp){
idx=i;
tmp=sum;
}
}
cout<<idx<<endl;
return 0;
}
問題 C: 花生採摘
題目描述
魯賓遜先生有一隻寵物猴,名叫多多。這天,他們兩個正沿着鄉間小路散步,突然發現路邊的告示牌上貼着一張小小的紙條:“歡迎免費品嚐我種的花生!——熊字”。
魯賓遜先生和多多都很開心,因爲花生正是他們的最愛。在告示牌背後,路邊真的有一塊花生田,花生植株整齊地排列成矩形網格〔如圖1〕。有經驗的多多一眼就能看出,每棵花生植株下的花生有多少。爲了訓練多多的算術,魯賓遜先生說:“你先找出花生最多的植株,去採摘它的花生;然後再找出剩下的植株裏花生最多的,去採摘它的花生;依此類推,不過你一定要在我限定的時間內回到路邊。”
我們假定多多在每個單位時間內,可以做以下四件事情中的一件:
1)從路邊跳到最靠近路邊〔即第一行〕的某棵花生植株;
2)從一棵植株跳到前後左右與之相鄰的另一棵植株;
3)採摘一棵植株下的花生;
4)從最靠近路邊〔即第一行〕的某棵花生植株跳回路邊。
現在給定一塊花生田的大小和花生的分佈,請問在限定時間內,多多最多可以採到多少個花生?注意可能只有部分植株下面長有花生,假設這些植株下的花生個數各不相同。
例如在樣例所示的花生田裏,只有位於(2,5),(3,7),(4,2),(5,4)的植株下長有花生,個數分別爲13,7,15,9。多多在21個單位時間內,最多可以採到37個花生。
輸入
輸入的第一行包括三個整數,M,N和K,用空格隔開;表示花生田的大小爲M*N〔1<=M,N<=20〕,多多采花生的限定時間爲K〔0<=K<=1000〕個單位時間。接下來的M行,每行包括N個非負整數,也用空格隔開;第i+1行的第j個整數Pij〔0<=Pij<=500〕表示花生田裏植株(i,j)下花生的數目,0表示該植株下沒有花生。
輸出
輸出包括一行,這一行只包含一個整數,即在限定時間內,多多最多可以採到花生的個數。
樣例輸入
6 7 21
0 0 0 0 0 0 0
0 0 0 0 13 0 0
0 0 0 0 0 0 7
0 15 0 0 0 0 0
0 0 0 9 0 0 0
0 0 0 0 0 0 0
樣例輸出
37
解題思路
貪心,在有限時間內獲得最多的花生,注意點:
- 起初和結束會花費1單位時間
- 猴子位移也會花費距離時間
- 採花生會花費1單位時間
- 當前花生能不能拿的條件是,判斷一下能不能回到路邊,不能回到路邊當前就不能採了
不過數據不是很強,勉強過了。嚴格一點的話可能會有數據會卡住。
AC代碼
#include<bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define endl '\n'
#define p pair<char,int>
using namespace std;
const int maxn=1e5+5;
int n,m,k,x;
vector<int> G[maxn];
set<int> st;
bool vis[maxn];
struct node{
int x,y,cc;
}stu[maxn];
bool cmp(node x,node y){
return x.cc>y.cc;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m>>k;
int cnt=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>x;
if(x) stu[cnt].x=i,stu[cnt].y=j,stu[cnt++].cc=x;
}
}
sort(stu,stu+cnt,cmp);
int res=0,ans=0,tmp=0;
ans+=stu[0].x;
k--;
if(ans<k){
ans+=2; //起初到路邊+採當前花生花費的時間
res+=stu[0].cc;
}
for(int i=1;i<cnt;i++){
ans+=(abs(stu[i].x-stu[i-1].x)+abs(stu[i].y-stu[i-1].y));
if(ans+stu[i].x<k){
ans+=1;
res+=stu[i].cc;
}
}
cout<<res<<endl;
return 0;
}
問題 D: FBI樹
題目描述
我們可以把由“0”和“1”組成的字符串分爲三類:全“0”串稱爲B串,全“1”串稱爲I串,既含“0”又含“1”的串那麼稱爲F串。
FBI樹是一種二叉樹[1],它的結點類型也包括F結點,B結點和I結點三種。由一個長度爲2N的“01”串S可以構造出一棵FBI樹T,遞歸的構造方法如下:
1)T的根結點爲R,其類型與串S的類型相同;
2)假設串S的長度大於1,將串S從中間分開,分爲等長的左右子串S1和S2;由左子串S1構造R的左子樹T1,由右子串S2構造R的右子樹T2。
現在給定一個長度爲2N的“01”串,請用上述構造方法構造出一棵FBI樹,並輸出它的後序遍歷序列[2]。
輸入
第一行是一個整數N〔1<=N<=128〕,數據保證n爲2的冪次方。
第二行是一個長度爲2N的“01”串。
輸出
輸出包括一行,這一行只包含一個字符串,即FBI樹的後序遍歷序列。
樣例輸入
4
10001011
樣例輸出
IBFBBBFIBFIIIFF
提示
[1]二叉樹:二叉樹是結點的有限集合,這個集合或爲空集,或由一個根結點和兩棵不相交的二叉樹組成。這兩棵不相交的二叉樹分別稱爲這個根結點的左子樹和右子樹。
[2]後序遍歷:後序遍歷是深度優先遍歷二叉樹的一種方法,它的遞歸定義是:先後序遍歷左子樹,再後序遍歷右子樹,最後訪問根。
解題思路
非常經典的一道二叉樹題。根據題意建樹,會發現這就是先序遍歷。而題目的輸出是後序遍歷,那麼我們就可以考慮,遞歸先序遍歷建樹,回溯的過程輸出,因爲先序遍歷回溯就是後序遍歷。
AC代碼
#include<bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define endl '\n'
#define p pair<char,int>
using namespace std;
const int maxn=1e5+5;
int n,m,cc;
char str[maxn];
int ans=0;
void output(int le,int re){
int k0=0,k1=0;
for(int i=le;i<=re;i++){
if(str[i]=='0') k0++;
else k1++;
}
if(k0&&k1) cout<<'F';
else if(!k0&&k1) cout<<'I';
else cout<<'B';
}
void fun(int l,int r){
if(l!=r){
fun(l,(l+r)/2);
fun((l+r)/2+1,r);
}
output(l,r);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
cin>>str;
int len=strlen(str)-1;
fun(0,len);
cout<<endl;
return 0;
}
問題 E: 火星人
題目描述
人類終於登上了火星的土地並且見到了神祕的火星人。人類和火星人都無法理解對方的語言,但是我們的科學家發明了一種用數字交流的方法。這種交流方法是這樣的,首先,火星人把一個非常大的數字告訴人類科學家,科學家破解這個數字的含義後,再把一個很小的數字加到這個大數上面,把結果告訴火星人,作爲人類的回答。
火星人用一種非常簡單的方式來表示數字——掰手指。火星人只有一隻手,但這隻手上有成千上萬的手指,這些手指排成一列,分別編號爲1,2,3……。火星人的任意兩根手指都能隨意交換位置,他們就是通過這方法計數的。
一個火星人用一個人類的手演示瞭如何用手指計數。如果把五根手指——拇指、食指、中指、無名指和小指分別編號爲1,2,3,4和5,當它們按正常順序排列時,形成了5位數12345,當你交換無名指和小指的位置時,會形成5位數12354,當你把五個手指的順序完全顛倒時,會形成54321,在所有能夠形成的120個5位數中,12345最小,它表示1;12354第二小,它表示2;54321最大,它表示120。下表展示了只有3根手指時能夠形成的6個3位數和它們代表的數字:
三進制數
123
132
213
231
312
321
代表的數字
1
2
3
4
5
6
現在你有幸成爲了第一個和火星人交流的地球人。一個火星人會讓你看他的手指,科學家會告訴你要加上去的很小的數。你的任務是,把火星人用手指表示的數與科學家告訴你的數相加,並根據相加的結果改變火星人手指的排列順序。輸入數據保證這個結果不會超出火星人手指能表示的範圍。
輸入
輸入包括三行,第一行有一個正整數N,表示火星人手指的數目〔1<=N<=10000〕。第二行是一個正整數M,表示要加上去的小整數〔1<=M<=100〕。下一行是1到N這N個整數的一個排列,用空格隔開,表示火星人手指的排列順序。
輸出
輸出只有一行,這一行含有N個整數,表示改變後的火星人手指的排列順序。每兩個相鄰的數中間用一個空格分開,不能有多餘的空格。
樣例輸入
5
3
1 2 3 4 5
樣例輸出
1 2 4 5 3
解題思路
文章挺長,但是講來講去,就是全排列問題,直接調用next_permutation
即可
AC代碼
#include<bits/stdc++.h>
#define endl '\n'
#define p pair<char,int>
using namespace std;
const int maxn=1e5+5;
int n,m;
stack<p> sk;
char str[maxn];
int a[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
for(int i=0;i<n;i++) cin>>a[i];
while(m--) next_permutation(a,a+n);
for(int i=0;i<n-1;i++) cout<<a[i]<<" ";
cout<<a[n-1]<<endl;
return 0;
}
問題 F: 小B旅遊
題目描述
小B在一個有N個城市M條道路的國家,每條道路連接的城市可以互相到達且每條道路小B都要花1步去走過它。現在他在1號城市,問他走P步最多能走多少個不同的城市?
輸入
輸入格式:第1行,三個正整數N、M、P,意義如題:接下來M行,每行兩個整數U、V,表示存在一條連接U、V的無向邊。
輸出
輸出格式:1行,一個整數,表示從1號城市出發走P步的所有情況,共能經過多少個不同的城市。
樣例輸入
4 4 2
1 2
1 3
2 3
3 4
樣例輸出
4
提示
數據規模:
1<=N<=100000,1<=M<=5000000,1<=P<=10000
解題思路
搜索題,直接搜就是,但是開始做的時候是從1開始搜,總是
不造被卡在哪了,後面換了一種方式,直接先加一步,從孩子結點開始搜,然後過了
AC代碼
#include<bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define endl '\n'
#define p pair<char,int>
using namespace std;
const int maxn=1e5+5;
int n,m,cc;
vector<int> G[maxn];
int vis[maxn];
int ans=0;
void dfs(int u,int cnt){
if(cnt>cc) return;
if(!vis[u]){
++ans;
vis[u]=1;
}
for(auto v:G[u])
if(!vis[v]) dfs(v,cnt+1);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m>>cc;
int u,v;
for(int i=0;i<m;i++){
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
for(auto u:G[1])
dfs(u,1);
cout<<ans<<endl;
return 0;
}
問題 G: 括號匹配
題目描述
括號主要有:大括號“{ }”、中括號“[ ]”、小括號“( )”。給定一個只包含左右括號的合法括號序列(序列長度2<=n<=10000),按右括號從左到右的順序輸出每一對配對的括號出現的位置(括號序列以0開始編號)
輸入
輸入格式:僅1行,表一個合法的括號序列
輸出
輸出格式:設括號序列有n個右括號,每行兩個整數l、r,表示配對的括號左括號出現在第l位,右括號出現在第r位。
樣例輸入
{()[()()]}()
樣例輸出
1 2
4 5
6 7
3 8
0 9
10 11
解題思路
括號匹配問題,經常性扯到使用棧的問題,根據題意,需要搞一個對子pair
存一下下標,每次取出棧頂元素和當前準備放入的元素進行比較,如果括號匹配成功即彈出棧,輸出下標即可
AC代碼
#include<bits/stdc++.h>
#define endl '\n'
#define p pair<char,int>
using namespace std;
const int maxn=1e5+5;
int n,m;
stack<p> sk;
char str[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>str;
for(int i=0;i<strlen(str);i++){
if(sk.empty()){
p p1=make_pair(str[i],i);
sk.push(p1);
}else if(str[i]=='}'){
p now=sk.top();
if(now.first=='{'){
cout<<now.second<<" "<<i<<endl;
sk.pop();
}
}else if(str[i]==']'){
p now=sk.top();
if(now.first=='['){
cout<<now.second<<" "<<i<<endl;
sk.pop();
}
}else if(str[i]==')'){
p now=sk.top();
if(now.first=='('){
cout<<now.second<<" "<<i<<endl;
sk.pop();
}
}else{
p p2=make_pair(str[i],i);
sk.push(p2);
}
}
return 0;
}
問題 H: 報數遊戲
題目描述
有n個小朋友,按順時針方向圍成一圈(編號從1—n),從第1號開始報數,一直數到m,數到m的小朋友退出圈外,剩下的小朋友再接着從1開始報數。
輸入
T組數據,第一行爲T(1<=T<=10)
接下來T行,每行用空格分開兩個整數n、m(1<=m,n<=10000)
輸出
輸出T行
每行一個答案表示第1號小朋友退出前,報數爲m的次數
樣例輸入
1
6 2
樣例輸出
4
解題思路
報數遊戲,與約瑟夫環問題有關,可以用遞歸求解,但是不太會做了,於是用瞭如下模擬,數據不強沒卡住…
AC代碼
#include<bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define endl '\n'
#define p pair<char,int>
using namespace std;
const int maxn=1e5+5;
int n,m,cc,t;
char str[maxn];
int ans=0;
int a[maxn];
vector<int> v;
vector<int>::iterator it;
int vis[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>t;
while(t--){
cin>>n>>m;
mst(vis,0);
int cnt=0,ans=-1;
v.clear();
for(int i=1;i<=n;i++) v.push_back(i);
while(1){
int len=v.size();
for(int i=0;i<len;i++){
if(!vis[v[i]])
++cnt;
if(!vis[v[i]]&&cnt==m){
vis[v[i]]=1;
++ans,cnt=0;
}
if(vis[1]) break;
}
if(vis[1]) break;
}
cout<<ans<<endl;
}
return 0;
}
問題 I: 小A的煩惱
題目描述
小A生活在一個神奇的國家,這個國家有N(N<=100000)個城市,還有M(M<=5000000)條道路連接兩城市。道路連接的兩個城市可以直接免費到達。小A比較煩惱,因爲他想知道每個城市能直接到達哪些城市,你能幫幫他嗎?保證每個城市都有道路與其連接。(注:按照輸入的道路順序輸出每個城市直接連接的城市,若有城市出現多次,則按最小出現次序輸出)
輸入
第1行包含兩個整數N和M;接下來M行,每行兩個整數描述一條道路連接的兩個城市的編號。
輸出
輸出N行,每行若干個用一個空格隔開的整數;第I行輸出的是與城市I直接相連城市編號,保證城市的出現按照道路輸入的先後順序出現。
樣例輸入
4 5
2 3
3 1
1 4
2 4
1 2
樣例輸出
3 4 2
3 4 1
2 1
1 2
解題思路
由題意,直接建圖輸出每個城市的子結點即可,不過總感覺沒這麼簡單吧,這個題還是卡了挺多人的… 可能還是數據不強吧…
AC代碼
#include<bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define endl '\n'
#define p pair<char,int>
using namespace std;
const int maxn=1e6+5;
int n,m;
vector<int> G[maxn];
set<int> st;
bool vis[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
for(int i=1;i<=n;i++){
for(auto v:G[i]){
cout<<v<<" ";
}
cout<<endl;
}
return 0;
}
問題 J: 一步之遙
題目描述
小B在一個有N個城市M條道路的國家,每條道路連接的城市可以互相到達且每條道路都要花1步去走過它。現在他在P號城市,問有多少城市走1步能到達該城市?
輸入
多組輸入
第1行,三個正整數N、M、P,意義如題。
接下來M行,每行兩個整數U、V,表示存在一條連接U、V的無向邊。(0<=N<=1000000,0<=M<=500000)
輸出
1行,走1步能到P城市的城市數量。
樣例輸入
4 4 1
1 2
1 3
2 3
3 4
樣例輸出
2
解題思路
問從p號城市,通過一步就能到達的城市數量。開始想着直接建圖,然後輸出p城市的子結點即可,然後用set直接去重一下,應該能過,不過一直卡在了33%
後面也嘗試了用vis數組判斷一下,也wa了。
最後,考慮只用看p城市相連邊的城市數目即可。直接用set不就好了嘛,下面代碼不是最簡代碼,最簡放後面
AC代碼
#include<bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define endl '\n'
#define p pair<char,int>
using namespace std;
const int maxn=1e6+5;
int n,m;
vector<int> G[maxn];
set<int> st;
bool vis[maxn];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int dd;
while(cin>>n>>m>>dd){
st.clear();
int cnt=0;
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
if(u==dd){
vis[v]=1;
++cnt;
st.insert(v);
}else if(v==dd){
vis[u]=1;
++cnt;
st.insert(u);
}
}
/*for(auto x:G[dd])
st.insert(x);
cout<<st.size()<<endl;*/
//cnt=st.size();
cout<<st.size()<<endl;
}
return 0;
}
簡化
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
int n,m;
set<int> st;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int dd;
while(cin>>n>>m>>dd){
st.clear();
int cnt=0;
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
if(u==dd)
st.insert(v);
else if(v==dd)
st.insert(u);
}
cout<<st.size()<<endl;
}
return 0;
}
學如逆水行舟,不進則退