好吧。。我的第二題現在還是掛著,算了,就把第二題無視掉吧,貼一下ACD的解題思路。
A 水題,不說太多,直接類比就可以了,用a數組表示指定位置的d,為了防止出現負數,把x都加了20000,讀取了一個x和一個d,判斷a[x+d]是否是-d即可,如果是,就說明找到了一對。
My Code:
#include <cstdio><br />#include <cstring><br />#include <cstdlib></p><p>using namespace std;</p><p>int a[100000];<br />const int step=20000;</p><p>int main()<br />{<br />int n;<br />int x,d;</p><p>scanf("%d",&n);<br />while(n--)<br />{<br />scanf("%d%d",&x,&d);<br />x+=step;<br />if(a[x+d]==-d)<br />{<br />puts("YES");<br />return 0;<br />}<br />else<br />a[x]=d;<br />}<br />puts("NO");</p><p>return 0;<br />}<br />
C 歐拉通路變形,因為要保證每個點都訪問到一次,於是就找從奇度數結點出發進行dfs,運用類似套圈法的方法來把結點加入路徑中。
還要注意因為範圍很大,所以需要離散化,或者用map來存放結點資訊。
My Code:
#include <cstdio><br />#include <cstring><br />#include <string><br />#include <vector><br />#include <map><br />#include <list></p><p>using namespace std;</p><p>int n;<br />map<int,list<int> > lst;//鄰接表<br />vector<int> ret;//最後結果<br />map<int,int> d;//度數<br />map<int,bool> use;//訪問標記</p><p>void dfs(int u)<br />{<br />int v;<br />list<int>& l=lst[u];<br />while(!l.empty())<br />{<br />v=*(l.begin());<br />l.pop_front();<br />if(!use[v])<br />dfs(v);<br />}<br />ret.push_back(u);<br />}</p><p>int main()<br />{<br />int n,s;<br />int x,y;</p><p>scanf("%d",&n);<br />for(int i=0;i<n;i++)<br />{<br />scanf("%d%d",&x,&y);<br />lst[x].push_back(y);<br />lst[y].push_back(x);<br />d[x]++;<br />d[y]++;<br />}</p><p>//找到度數是奇數的點作為起點<br />for(map<int,int>::iterator it=d.begin();it!=d.end();it++)<br />{<br />if((it->second)%2)<br />{<br />s=it->first;<br />break;<br />}<br />}</p><p>dfs(s);<br />for(int i=0;i<n;i++)<br />printf("%d ",ret[i]);<br />printf("%d/n",ret[n]);</p><p>return 0;<br />}<br />
D 經典LCA問題,為了得到有順序的結點,我們求出相鄰的結點的LCA即可,建議大家先看相關的資料再理解這個演算法。
My Code:
#include <cstdio><br />#include <cstring><br />#include <cstdlib><br />#include <cmath><br />#include <algorithm></p><p>using namespace std;</p><p>const int MAX=305;<br />int lst[MAX][MAX];//鄰接表<br />int father[MAX];//父親結點<br />bool vis[MAX];//訪問數組<br />bool leaf[MAX];//是否是葉子<br />int order[MAX];//葉子的順序<br />int lca[MAX];//order[i]和order[i+1]的LCA</p><p>void dfs(int x)//dfs判斷葉子數量<br />{<br />bool flag=false;<br />vis[x]=true;<br />for(int i=1;i<=lst[x][0];i++)<br />{<br />if(!vis[lst[x][i]])<br />{<br />flag=true;<br />father[lst[x][i]]=x;<br />dfs(lst[x][i]);<br />}<br />}<br />if(!flag)<br />leaf[x]=true;<br />}</p><p>int st[MAX],cnt[MAX][MAX];<br />int ret[600000];</p><p>int main()<br />{<br />int x,y,n;<br />int nleaf,temp,P,top;</p><p>scanf("%d",&n);<br />for(int i=1;i<=n;i++)<br />lst[i][0]=0;<br />for(int i=1;i<n;i++)<br />{<br />scanf("%d%d",&x,&y);<br />lst[x][0]++;<br />lst[x][lst[x][0]]=y;<br />lst[y][0]++;<br />lst[y][lst[y][0]]=x;<br />}<br />for(int i=1;i<=n;i++)<br />{<br />vis[i]=false;<br />leaf[i]=false;<br />}<br />father[1]=-1;<br />dfs(1);<br />nleaf=0;<br />for(int i=1;i<=n;i++)<br />if(leaf[i])<br />nleaf++;<br />for(int i=1;i<=nleaf;i++)<br />scanf("%d",&order[i]);<br />for(int i=1;i<nleaf;i++)<br />{<br />for(int j=1;j<=n;j++)<br />vis[j]=false;<br />temp=order[i];<br />while(temp!=1)//向上尋找祖先<br />{<br />vis[temp]=1;<br />temp=father[temp];<br />}<br />temp=order[i+1];<br />vis[1]=true;<br />while(temp!=1)<br />{<br />if(vis[temp])<br />break;<br />temp=father[temp];<br />}<br />lca[i]=temp;<br />}<br />order[0]=1;<br />lca[0]=1;<br />lca[nleaf]=1;<br />order[nleaf+1]=1;<br />for(int i=1;i<=n;i++)<br />for(int j=1;j<=n;j++)<br />cnt[i][j]=0;<br />P=1;<br />ret[0]=1;<br />for(int i=1;i<=nleaf;i++)<br />{<br />temp=order[i];<br />top=0;<br />while(temp!=lca[i-1])<br />{<br />st[top++]=temp;<br />cnt[temp][father[temp]]++;<br />cnt[father[temp]][temp]++;<br />if(cnt[father[temp]][temp]>2)<br />{<br />puts("-1");<br />return 0;<br />}<br />temp=father[temp];<br />}<br />for(int j=top-1;j>=0;j--)<br />ret[P++]=st[j];<br />temp=order[i];<br />top=0;<br />while(temp!=lca[i])<br />{<br />st[top++]=temp;<br />cnt[temp][father[temp]]++;<br />cnt[father[temp]][temp]++;<br />if(cnt[father[temp]][temp]>2)<br />{<br />puts("-1");<br />return 0;<br />}<br />temp=father[temp];<br />}<br />st[top]=lca[i];<br />for(int j=1;j<=top;j++)<br />ret[P++]=st[j];<br />}<br />for(int i=0;i<P-1;i++)<br />printf("%d ",ret[i]);<br />printf("%d/n",ret[P-1]);<br />}<br />