HNUCM Contest1088 - 2020年春季ACM集訓隊熱身賽-第2場 比賽題解

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;
}
學如逆水行舟,不進則退
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章