@sensitive-cs
2017-03-28T08:35:43.000000Z
字数 1084
阅读 817
to be write : 最小表示法
题意:
给出一个字符串,求出这个字符串的最小表示法,即字典序最小。
思路:
循环比较,具体看紫书。需要注意的是此题与循环队列的联系。
代码:
#include <stdio.h>
#include <string.h>
char s[10005];
int les(int n,int p,int q)
{
for (int i = 0;i < n;i++)
if (s[(p+i) % n] != s[(q+i)%n]) return s[(p+i) % n] < s[(q+i)%n];
return 0;
}
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
int ans = 0;
scanf("%s",s);
int len = strlen(s);
for (int i = 1;i < len;i++)
if (les(len,i,ans)) ans = i;
printf("%d\n",ans+1);
}
return 0;
}
poj3974:palindrome
题意:
找出一个字符串的最长回文字串的长度。
思路:
马拉车算法,裸题。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 1000020;
int p[2*maxn + 50];
char s[2*maxn + 50];
char ch[2*maxn + 50];
int main()
{
int cnt = 1;
while (scanf(" %s",s) != EOF)
{
if (s[0] == 'E') break;
memset(ch,0,sizeof(ch));
memset(p,0,sizeof(p));
ch[0] = '$',ch[1] = '#';
int len = 1,maxright = 0,pos = 0;
int ll = 0;
while (s[ll] != '\0')
{
ch[++len] = s[ll];
ch[++len] = '#';
ll++;
}
for (int i = 2;i <= len;i++)
{
if (i < maxright) p[i] = min(p[2*pos-i],maxright-i);
else p[i] = 1;
while (ch[i-p[i]] == ch[i+p[i]]) p[i]++;
if (i+p[i] > maxright)
{
maxright = i+p[i];
pos = i;
}
}
ch[len+1] = '\0';
int ans = 0;
for (int i = 2;i <= len;i++)
ans = max(ans,p[i]-1);
printf("Case %d: %d\n",cnt++,ans);
}
return 0;
}