今天悲劇的第一題沒看懂題,好吧,不會做,B題最簡單,放出來。
這題的思路實際上是並查集,先定義一個數組st表示現在的狀態,目標狀態是1,2,3,……,n,那麼,每次尋找i和i+v[i]和i-v[i]三個數,把他們合并,表示他們可以互相轉換,那麼用O(n)的複雜度掃一遍,可以把全部的元素屬於什麼集合預先處理出來,最後只要判斷st[i]和i是不是一個集合裡的就可以了。
今天無聊複習C++,封裝了個並查集的類,剛好用上。。。
My Code:
#include <cstdio></p><p>using namespace std;</p><p>class Set<br />{<br />private:<br />const static int maxsize=110000;<br />int p[maxsize];<br />int rank[maxsize];<br />int size;<br />void Link(int x,int y);<br />void init();<br />public:<br />Set();<br />Set(const int& n);<br />Set(Set& st);<br />int Find(int x);<br />void Union(int x,int y);<br />bool Same(int x,int y);<br />bool Union2(int x,int y);<br />bool IsRoot(int x);<br />void Reset();<br />void Reset(const int& n);<br />int Size();<br />};</p><p>void Set::Link(int x,int y)<br />{<br />if(rank[x]>rank[y])<br />p[y]=x;<br />else<br />{<br />p[x]=y;<br />if(rank[x]==rank[y])<br />rank[y]++;<br />}<br />}</p><p>int Set::Size()<br />{<br />return size;<br />}</p><p>void Set::init()<br />{<br />for(int i=1;i<=size;i++)<br />{<br />p[i]=i;<br />rank[i]=0;<br />}<br />}</p><p>Set::Set()<br />{<br />size=maxsize-1;<br />init();<br />}</p><p>Set::Set(const int& n)<br />{<br />size=n;<br />if(n<maxsize)<br />init();<br />}</p><p>Set::Set(Set& st)<br />{<br />size=st.size;<br />for(int i=1;i<=size;i++)<br />{<br />p[i]=st.p[i];<br />rank[i]=st.rank[i];<br />}<br />}</p><p>int Set::Find(int x)<br />{<br />if(!IsRoot(x))<br />p[x]=Find(p[x]);<br />return p[x];<br />}</p><p>void Set::Union(int x,int y)<br />{<br />int px=Find(x);<br />int py=Find(y);</p><p>if(px!=py)<br />{<br />Link(px,py);<br />}<br />}</p><p>bool Set::Same(int x,int y)<br />{<br />return Find(x)==Find(y);<br />}</p><p>bool Set::Union2(int x,int y)<br />{<br />int px=Find(x);<br />int py=Find(y);</p><p>if(px!=py)<br />{<br />Link(px,py);<br />return false;<br />}<br />else<br />return true;<br />}</p><p>bool Set::IsRoot(int x)<br />{<br />return p[x]==x;<br />}</p><p>void Set::Reset()<br />{<br />size=maxsize-1;<br />init();<br />}</p><p>void Set::Reset(const int& n)<br />{<br />size=n;<br />if(n<maxsize)<br />init();<br />}</p><p>int main()<br />{<br />int n;<br />int a[110];<br />int v;</p><p>scanf("%d",&n);<br />Set st(n);<br />for(int i=1;i<=n;i++)<br />{<br />scanf("%d",&a[i]);<br />}<br />for(int i=1;i<=n;i++)<br />{<br />scanf("%d",&v);<br />if(i+v<=n)<br />st.Union(a[i],a[i+v]);<br />if(i-v>=1)<br />st.Union(a[i],a[i-v]);<br />}</p><p>for(int i=1;i<=n;i++)<br />{<br />if(!st.Same(i,a[i]))<br />{<br />puts("NO");<br />return 0;<br />}<br />}<br />puts("YES");</p><p>return 0;<br />}<br />