码迷,mamicode.com
首页 > 其他好文 > 详细

字符串练习

时间:2019-09-08 00:08:18      阅读:92      评论:0      收藏:0      [点我收藏+]

标签:name   表示   ||   col   win   cos   cstring   getchar   lse   

1、HDU3374 String Problem  KMP+最小表示法  **

大致题意:求出给定字符串的最小表示和最大表示以及出现次数

思路:环状字符串某一链状字符串出现的次数为循环节个数,用Next数组求解。然后是字符串的最大表示法和最小表示法。

AC代码:

技术图片
 1 #include<iostream>
 2 #include<sstream>
 3 #include<fstream>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<iomanip>
 7 #include<cstdlib>
 8 #include<cctype>
 9 #include<vector>
10 #include<string>
11 #include<cmath>
12 #include<ctime>
13 #include<stack>
14 #include<queue>
15 #include<map>
16 #include<set>
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define random(a,b) (rand()%(b-a+1)+a)
19 #define ll long long
20 #define ull unsigned long long
21 #define e 2.71828182
22 #define Pi acos(-1.0)
23 #define ls(rt) (rt<<1)
24 #define rs(rt) (rt<<1|1)
25 #define lowbit(x) (x&(-x))
26 using namespace std;
27 const int MAXN=1e6+5;
28 string str;
29 int Next[MAXN],len;
30 int getmin()
31 {
32     int i=0,j=1,k=0;
33     while(i<len&&j<len&&k<len)
34     {
35         if(str[(i+k)%len]==str[(j+k)%len]) k++;
36         else
37         {
38             if(str[(i+k)%len]>str[(j+k)%len]) i+=k+1;
39             else j+=k+1;
40             if(i==j) j++;
41             k=0;
42         }
43     }    
44     return min(i,j)+1;
45 } 
46 int getmax()
47 {
48     int i=0,j=1,k=0;
49     while(i<len&&j<len&&k<len)
50     {
51         if(str[(i+k)%len]==str[(j+k)%len]) k++;
52         else
53         {
54             if(str[(i+k)%len]>str[(j+k)%len]) j+=k+1;
55             else i+=k+1;
56             if(i==j) j++;
57             k=0;
58         }
59     }    
60     return min(i,j)+1;
61 }
62 void GetNext()
63 {
64     int k=Next[0]=-1;
65     int j=0;
66     while(j<len)
67     {
68         if(k==-1||str[j]==str[k]) Next[++j]=++k;
69         else k=Next[k];
70     }
71 }
72 int read()
73 {
74     int s=1,x=0;
75     char ch=getchar();
76     while(!isdigit(ch)) {if(ch==-) s=-1;ch=getchar();}
77     while(isdigit(ch)) {x=10*x+ch-0;ch=getchar();}
78     return x*s;
79 }
80 
81 int main()
82 {
83     ios::sync_with_stdio(false);
84     cin.tie(0);cout.tie(0);
85     while(cin>>str)
86     {
87         len=str.size();
88         GetNext();
89         int t=1;
90         if(Next[len]!=0&&len%(len-Next[len])==0) t=len/(len-Next[len]);
91         cout<<getmin()<< <<t<< <<getmax()<< <<t<<endl;
92     }
93 }
View Code

 

2、POJ3349 Snowflake Snow Snowflakes  Hash+最小表示法  **

大致题意:每一片雪花都有各自的6个arm值,如果两片雪花从相同或者不同位置开始顺时针数或者逆时针数可以匹配上,那么这两片雪花就是相等的。给定n片雪花,判断是否存在有相同的两片雪花。

思路:利用Hash匹配是否有相等的两片雪花;利用最小表示法表示每片雪花,那么每片雪花就只有两个Hash值需要判断,正序或逆序。

AC代码:

技术图片
 1 #include<iostream>
 2 #include<sstream>
 3 #include<fstream>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<iomanip>
 7 #include<cstdlib>
 8 #include<cctype>
 9 #include<vector>
10 #include<string>
11 #include<cmath>
12 #include<ctime>
13 #include<stack>
14 #include<queue>
15 #include<map>
16 #include<set>
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define random(a,b) (rand()%(b-a+1)+a)
19 #define ll long long
20 #define ull unsigned long long
21 #define e 2.71828182
22 #define Pi acos(-1.0)
23 #define ls(rt) (rt<<1)
24 #define rs(rt) (rt<<1|1)
25 #define lowbit(x) (x&(-x))
26 using namespace std;
27 const int Base=23333;
28 const int MOD=1e3+7;
29 int a[6];
30 int n; 
31 vector<ull> HashTable[MOD];
32 void add_edge(ull ha)
33 {
34     int pos=ha%MOD;
35     HashTable[pos].push_back(ha);
36 }
37 bool find(ull ha)
38 {
39     int pos=ha%MOD;
40     for(int i=0;i<HashTable[pos].size();++i)
41     if(HashTable[pos][i]==ha) return true;
42     return false;
43 }
44 int getmin()
45 {
46     int i=0,j=1,k=0;
47     while(i<6&&j<6&&k<6)
48     {
49         if(a[(i+k)%6]==a[(j+k)%6]) k++;
50         else
51         {
52             if(a[(i+k)%6]>a[(j+k)%6]) i+=k+1;
53             else j+=k+1;
54             if(i==j) j++;
55             k=0;
56         }
57     }
58     return min(i,j);
59 }
60 int read()
61 {
62     int s=1,x=0;
63     char ch=getchar();
64     while(!isdigit(ch)) {if(ch==-) s=-1;ch=getchar();}
65     while(isdigit(ch)) {x=10*x+ch-0;ch=getchar();}
66     return x*s;
67 }
68 int main()
69 {
70     n=read();
71     ull ha;
72     bool flag=true;
73     while(n--)
74     {
75         for(int i=0;i<6;++i)
76         a[i]=read();
77         if(flag)
78         {
79             int idx=getmin();
80             ha=0;
81             for(int i=idx;i<idx+6;++i)//正序 
82             ha=ha*Base+a[i%6];
83             if(find(ha)) flag=false;
84             add_edge(ha);
85             ha=0;
86             for(int i=idx;i>idx-6;--i)//逆序 
87             ha=ha*Base+a[(i+6)%6];
88             if(find(ha)) flag=false;
89             add_edge(ha);
90         }
91     }
92     if(flag) cout<<"No two snowflakes are alike.\n";
93     else cout<<"Twin snowflakes found.";
94 }
View Code

 

字符串练习

标签:name   表示   ||   col   win   cos   cstring   getchar   lse   

原文地址:https://www.cnblogs.com/wangzhebufangqi/p/11483944.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!