Codeforces Beta Round #23

來源:互聯網
上載者:User

http://www.codeforces.com/contest/23

 

下面B,C都來自iSea大神的題解;

A題

【題意】

給定一個串,求其最長重複子串長度,

 

【分析】

考慮到長度為100,可以暴力,我考慮到在本機可以貼模板,用尾碼數組寫的,取height數組的最大值輸出即可;

 

【暴力的好的代碼】

 

 

 

【尾碼數組代碼】

/*Apr2,2011 5:19:02PM yimao A-Youre Given a String... GNUC++ Accepted 30ms 1400KB*/ </p><p>http://codeforces.com/contest/23/problem/A</p><p>#define N 110<br />int r[N],sa[N],rank[N],height[N];<br />int wss[30],wa[N],wb[N],wv[N];<br />int cmp(int *r,int a,int b,int t)<br />{return r[a]==r[b]&&r[a+t]==r[b+t];}<br />void Da(int *r,int *sa,int n,int m){<br /> int i,j,p,*x=wa,*y=wb,*t;<br /> for(i=0;i<m;i++)wss[i]=0;<br /> for(i=0;i<n;i++)wss[x[i]=r[i]]++;<br /> for(i=1;i<m;i++)wss[i]+= wss[i-1];<br /> for(i=n-1;i>=0;i--)sa[--wss[x[i]]]=i;<br /> for(j=1,p=1;p<n;j*=2,m=p){<br /> for(p=0,i=n-j;i<n;i++) y[p++]=i;<br /> for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;<br /> for(i=0;i<n;i++)wv[i]=x[y[i]];<br /> for(i=0;i<m;i++)wss[i]=0;<br /> for(i=0;i<n;i++)wss[wv[i]]++;<br /> for(i=1;i<m;i++)wss[i]+= wss[i-1];<br /> for(i=n-1;i>=0;i--)sa[--wss[wv[i]]]=y[i];<br /> for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)<br /> x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;<br /> }<br /> return;<br />}<br />void Cal_height(int *r,int *sa,int n){<br /> int i,j,k=0;<br /> for(i=1;i<=n;i++) rank[sa[i]]=i;<br /> for(i=0;i<n;height[rank[i++]]=k)<br /> for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++); // == ;<br />}<br />int main()<br />{<br /> char ch[110];<br /> while(gets(ch))<br /> {<br /> int n=strlen(ch);<br /> for(int i=0;i<n;i++)r[i]=ch[i]-'a'+1;<br /> r[n]=0;<br /> Da(r,sa,n+1,28);<br /> Cal_height(r,sa,n);<br /> cout<<*max_element(height+2,height+1+n)<<endl;<br /> }<br />}<br />/*<br />abcd<br />ababa<br />zzz<br />*/

 

 

B題

【題意】

問n個人蔘加聚會,先把沒有朋友的人驅逐,然後把只有一個朋友的人驅逐,然後把只有兩個朋友的人驅逐……最後把有n-1個朋友的人驅逐,問最後有多少人留在了這次聚會中;

換成圖論裡的話說就是一個無向圖中,去掉度為0的點,然後去掉度為1的點……;

 

【分析】

答案是n-2,分配方法是n個點取完全圖,然後任意選兩個相連的點,去掉,它們的度為n-1,那麼我們接下來要去的點的度數為n,而剩下的點的度皆是n-3,可以留下來了;

 

【代碼】

/*Apr24,2011 3:25:51PM yimao B-Party GNU C++ Accepted 230ms 1400KB*/<br />//http://codeforces.com/contest/23/problem/B<br />//from:http://hi.baidu.com/%D2%BB%CE%BB%C1%E3/blog/item/9d7e2a1f1daa70f91ad57618.html<br />int main()<br />{<br /> int T,n;<br /> cin>>T;<br /> while(T--)<br /> {<br /> cin>>n;<br /> if(n<=2) n=0; //注意n<=2時,輸出為0;<br /> else n-=2;<br /> cout<<n<<endl;<br /> }<br />}

 

 

C題

【題意】

給定n,然後是n+n-1組數,每組數是一個x,y,要求選出n組數,使得n組數的x之和大於總的x之和的一半,y之和大於總的y之和的一半;

 

【分析】

從iSea大神那裡學到的方法,好牛!對x從小到大排序,然後對於每兩組數取y更大的那組;

原理嘛,不清楚,但卻是是這樣,自己可以寫下例如n=5,排序後:

x1  y1

x2  y2   (1)

x3  y3

x4  y4   (2)

x5  y5

x6  y6   (3)

x7  y7

x8  y8   (4)

x9  y9

 

首先我們選y更大的那組,對y是保證滿足條件,下面分析x,從(2)無論選哪個x,一定大於(1)中的兩個x,從(3)中選的x一定大於(2)中的兩個x,……最後是x9一定大於(4)中的x,這樣選我們保證了未選的四個數,都有比之大的數,也就是選出的x的和一定大於總和的一半,這個思想十分值得學習,ORZ!

 

 

【代碼】

/*Apr24,2011 4:06:40PM yimao C-Oranges and Apples GNUC++ Accepted 250ms 3700KB*/<br />//http:codeforces.com/contest/23/problem/C<br />//from: http://hi.baidu.com/%D2%BB%CE%BB%C1%E3/blog/item/9d7e2a1f1daa70f91ad57618.html<br />struct Data{<br /> int x,y,idx;<br /> bool operator<(Data t)const{<br /> return x<t.x;<br /> }<br />}a[200020];<br />int main()<br />{<br /> int T,n,i;<br /> cin>>T;<br /> while(T--)<br /> {<br /> cin>>n;<br /> n+= n-1;<br /> for(i=1;i<=n;i++){<br /> scanf("%d%d",&a[i].x,&a[i].y);<br /> a[i].idx=i;<br /> }<br /> sort(a+1,a+1+n);<br /> puts("YES");<br /> for(i=2;i<n;i+=2)<br /> printf("%d ",a[a[i].y>a[i-1].y?i:i-1].idx);<br /> printf("%d/n",a[n].idx);<br /> }<br />}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.