標籤:檔案 space 長度 sam blog tin 需要 algo max
codevs 1051 接龍遊戲http://codevs.cn/problem/1051/題目描述 Description
給出了N個單詞,已經按長度排好了序。如果某單詞i是某單詞j的首碼,i->j算一次接龍(兩個相同的單詞不能算接龍)。
你的任務是:對於輸入的單詞,找出最長的龍。
輸入描述 Input Description
第一行為N(1<=N<=105)。以下N行每行一個單詞(由小寫組成),已經按長度排序。(每個單詞長度<50)
輸出描述 Output Description
僅一個數,為最長的龍的長度。
範例輸入 Sample Input
5
i
a
int
able
inter
範例輸出 Sample Output
3
資料範圍及提示 Data Size & Hint
1<=N<=105
方法一:類比棧
先將輸入資料按字典序排序,然後依次枚舉,棧頂是當前字串的首碼,就入棧,否則,棧頂出棧直至當前字串可以入棧。在此期間,隨時更新接龍最大值
以範例為例:設棧為stack[],答案為ans
排序後為:a able i int inter
1、棧為空白,a入棧 stack:a ans=1
2、a是able的首碼,able入棧 stack:a able ans=2
3、able不是i的首碼, able出棧 stack:a ans=2
4、a不是i的首碼,a出棧 stack: ans=2
5、棧為空白,i入棧 stack:i ans=2
6、i是int的首碼,int入棧 stack:i int ans=2
7、int是inter的首碼,inter入棧 stack:i int inter ans=3
結束
截取首碼時,可以使用assign函數,標頭檔:cstring
格式:p.assign(s,start,len) 在s中從位置start開始,截取長尾len的字串複製給p
附:string常用函數:http://www.cnblogs.com/wangkangluo1/archive/2011/07/22/2114118.html
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;string s[100001],stack[100001];int n,top,ans;bool cmp(string a,string b){ return a<b;//按字典序排序,string可以直接調用<,>,=,與int,double一樣 }int main(){ cin>>n; for(int i=1;i<=n;i++) cin>>s[i];//s存原資料 sort(s+1,s+n+1,cmp);//按字典序排序 stack[top++]+=s[1];//第一個先入棧 ans++;//至少有一個 for(int k=2;k<=n;k++)//所有的top均為開區間 { int l=stack[top-1].size();//當前棧頂元素的長度,即s[k]要想入棧,要判斷首碼的長度 string p; p.assign(s[k],0,l);//在s[k]中從第0位開始,截取長度為l的字串,賦值給p if(p==stack[top-1])//因為top為開區間,所以比較的是top-1 { if(s[k].size()==stack[top-1].size()) continue;//首碼相等,總單詞長度也相等,那麼這兩個單詞相等,題目說了不能算 stack[top++]=s[k];//可以入棧 } else { while(top&&stack[top-1]!=p.assign(s[k],0,l))//一直退到能入棧或棧為空白 { top--; if(top)//棧為空白時,top=0,不加這句會RE l=stack[top-1].size();//l轉變為下一個要比較的單詞的長度 } stack[top++]=s[k];//入棧 } ans=max(ans,top);//更新答案 } cout<<ans;}
方法二:http://www.cnblogs.com/IUUUUUUUskyyy/p/6193997.html
兩個錯誤:1.退棧時,在比較的是當前棧頂元素,所以l、p需要更新。開始做的時候沒有更新,一直用最初的棧頂元素比
2、ans初值為0,for迴圈從2開始,所以如果只有1個元素,輸出0,但應該輸出1
codevs 1051 接龍遊戲