您的位置:首页 > 其它

HDU 4162 Shape Number

2016-06-03 21:26 344 查看

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4162

题意:

求给定字符的一阶差分链的最小表示。

题解:

先求一阶差分链,再求一阶差分链的最小表示法。

代码:

跑了670MS

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 3e5 + 10;

char s1[maxn],s2[maxn];

int solve(char *s) {
int i = 0, j = 1, k = 0,len=strlen(s);
while (i < len&&j < len&&k<len) {
int t = s[(i + k) % len] - s[(j + k) % len];
if (!t) k++;
else {
if (t > 0) i = i + k + 1;
else j = j + k + 1;
if (i == j) j++;
k = 0;
}
}
return i < j ? i : j;
}

int main() {
while (scanf("%s", s1) == 1) {
int len = strlen(s1);
for (int i = 0; i < len; i++) {
s2[i] = (s1[(i + 1) % len] - s1[i] + 8) % 8 + '0';
}
s2[len] = '\0';
//cout << s2 << endl;
int pos = solve(s2);
for (int i = 0; i < len; i++) {
printf("%c", s2[(pos + i) % len]);
}
printf("\n");
}
return 0;
}


贴个后缀数组的解法:

跑了2527MS

#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)

typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;

const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;

const int maxn = 3e5 + 10;

char s1[maxn],s2[maxn];

struct SuffixArray{
char s[maxn];
int sa[maxn],t[maxn],t2[maxn],c[maxn];
int n,m;
void init(int n,int m){
this->n=n;
this->m=m;
}
void build_sa(){
int i,*x=t,*y=t2;
for(i=0;i<m;i++) c[i]=0;
for(i=0;i<n;i++) c[x[i]=s[i]]++;
for(i=1;i<m;i++) c[i]+=c[i-1];
for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i;
for(int k=1;k<=n;k<<=1){
int p=0;
//            for(i=n-k;i<n;i++) y[p++]=i;
//            for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(i=0;i<n;i++) y[p++]=(sa[i]-k+n)%n;

for(i=0;i<m;i++) c[i]=0;
for(i=0;i<n;i++) c[x[y[i]]]++;
for(i=1;i<m;i++) c[i]+=c[i-1];
for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];

swap(x,y);
p=1; x[sa[0]]=0;
for(i=1;i<n;i++){
x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
}
if(p>=n) break;
m=p;
}
}
}mysa;

int main() {
while (scanf("%s", s1) == 1) {
int len = strlen(s1);
mysa.init(len,256);
for (int i = 0; i < len; i++) {
s2[i] = (s1[(i + 1) % len] - s1[i] + 8) % 8 + '0';
}
s2[len] = '\0';
strcpy(mysa.s,s2);
mysa.build_sa();

for(int p=mysa.sa[0];p<mysa.sa[0]+mysa.n;p++){
printf("%c",mysa.s[p%mysa.n]);
}
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: