hdu5442(2015长春网络赛F题)
2015-09-17 17:01
197 查看
题意:
给出一个字符串,只由‘a’~‘z'组成,字符串是一个首尾相接的串。我们要找到一个起点,顺时针或者逆时针的读这个串,找到字典序最大的读法,如果有多种,输出起点坐标小的那个,如果起点坐标一样,输出顺时针的那个。
思路:
把串变成倍长的,反着再处理一次。
坑死我了。。。用罗穗骞的da算法超时,用dc3RE,用了个网上找的,过了。
代码:
附上TLE的da算法代码:
[b]附上RE的dc3算法代码:
给出一个字符串,只由‘a’~‘z'组成,字符串是一个首尾相接的串。我们要找到一个起点,顺时针或者逆时针的读这个串,找到字典序最大的读法,如果有多种,输出起点坐标小的那个,如果起点坐标一样,输出顺时针的那个。
思路:
把串变成倍长的,反着再处理一次。
坑死我了。。。用罗穗骞的da算法超时,用dc3RE,用了个网上找的,过了。
代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <set> #include <algorithm> #include <math.h> using namespace std; typedef long long ll; const int N=1e5; int sa ,height ,Rank ,tmp ,top ; char s ; void dc3(int n){ int i,j,len,na; na=(n<256?256:n); memset(top,0,na*sizeof(int)); for(i=0;i<n;i++)top[Rank[i]=s[i]&0xff]++; for(i=1;i<na;i++)top[i]+=top[i-1]; for(i=0;i<n;i++)sa[--top[Rank[i]]]=i; for(len=1;len<n;len<<=1){ for(i=0;i<n;i++){ j=sa[i]-len;if(j<0)j+=n; tmp[top[Rank[j]]++]=j; } sa[tmp[top[0]=0]]=j=0; for(i=1;i<n;i++){ if(Rank[tmp[i]]!=Rank[tmp[i-1]]|| Rank[tmp[i]+len]!=Rank[tmp[i-1]+len]) top[++j]=i; sa[tmp[i]]=j; } memcpy(Rank,sa,n*sizeof(int)); memcpy(sa,tmp,n*sizeof(int)); if(j>=n-1)break; } } char rt ; void _print(int ans1,int ans2,int n) { int t1=ans1; int t2=ans2; t2+=n; for(int i=0;i<n;i++){ if(rt[t1]>rt[t2]) { printf("%d 0\n",ans1+1); return ; } if(rt[t1]<rt[t2]) { printf("%d 1\n",ans2+1); return ; } t1++; if(t1>n+n) break; t2--; if(t2<0) break; } if(ans1<ans2) printf("%d 0\n",ans1+1); else if(ans2<ans1) printf("%d 1\n",ans2+1); else printf("%d 0\n",ans1+1); } int main() { int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); scanf("%s",s); for(int i=0;i<n;i++) { s[i+n]=s[i]; rt[i]=rt[i+n]=s[i]; } s[n+n]=0; dc3(n+n+1); // for(int i=0;i<n+n;i++) // printf("1--%d\n",Rank[i]); int ans1=0; for(int i=1;i<n;i++) { if(Rank[i]>Rank[ans1]) ans1=i; } for(int i=0;i<n;i++) { s[i]=rt[n-i-1]; s[i+n]=rt[n-i-1]; } s[n+n]='z'+1; dc3(n+n+1); int ans2=0; for(int i=1;i<n;i++) { if(Rank[i]>Rank[ans2]) ans2=i; } ans2=n-1-ans2; _print(ans1,ans2,n); // printf("%d %d\n",ans1,ans2); // for(int i=0;i<n+n;i++) // printf("2--%d\n",Rank[i]); } return 0; }
附上TLE的da算法代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define maxn 20005 int wa[maxn],wb[maxn],wv[maxn],_ws[maxn]; int cmp(int *r,int a,int b,int l) {return r[a]==r&&r[a+l]==r[b+l];} void da(char *r,int *sa,int n,int m) { int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) _ws[i]=0; for(i=0;i<n;i++) _ws[x[i]=r[i]]++; for(i=1;i<m;i++) _ws[i]+=_ws[i-1]; for(i=n-1;i>=0;i--) sa[--_ws[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { for(p=0,i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0;i<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++) _ws[i]=0; for(i=0;i<n;i++) _ws[wv[i]]++; for(i=1;i<m;i++) _ws[i]+=_ws[i-1]; for(i=n-1;i>=0;i--) sa[--_ws[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } return; } int _rank[maxn],_height[maxn]; void cal_height(char *r,int *sa,int n) { int i,j,k=0; for(i=1;i<=n;i++) _rank[sa[i]]=i; for(i=0;i<n;_height[_rank[i++]]=k) for(k?k--:0,j=sa[_rank[i]-1];r[i+k]==r[j+k];k++); return; } char r[maxn],rt[maxn]; int sa[maxn]; void _print(int ans1,int ans2,int n) { int t1=ans1; int t2=ans2; t2+=n; for(int i=0;i<n;i++){ if(rt[t1]>rt[t2]) { printf("%d 0\n",ans1+1); return ; } if(rt[t1]<rt[t2]) { printf("%d 1\n",ans2+1); return ; } t1++; t2--; } if(ans1<ans2) printf("%d 0\n",ans1+1); else if(ans2<ans1) printf("%d 1\n",ans2+1); else printf("%d 0\n",ans1+1); } int main() { int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); scanf("%s",r); for(int i=0;i<n;i++) { r[i+n]=r[i]; rt[i]=rt[i+n]=r[i]; } r[n+n]=0; da(r,sa,n+n+1,200); cal_height(r,sa,n+n); // for(int i=0;i<n+n;i++) // printf("1--%d\n",_rank[i]); int ans1=0; for(int i=1;i<n;i++) { if(_rank[i]>_rank[ans1]) ans1=i; } for(int i=0;i<n;i++) { r[i]=rt[n-i-1]; r[i+n]=rt[n-i-1]; } r[n+n]='z'+1; da(r,sa,n+n+1,200); cal_height(r,sa,n+n); int ans2=0; for(int i=1;i<n;i++) { if(_rank[i]>_rank[ans2]) ans2=i; } ans2=n-1-ans2; _print(ans1,ans2,n); // printf("%d %d\n",ans1,ans2); // for(int i=0;i<n+n;i++) // printf("2--%d\n",_rank[i]); } return 0; }
[b]附上RE的dc3算法代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define maxn 1000003 #define F(x) ((x)/3+((x)%3==1?0:tb)) #define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2) int wa[maxn],wb[maxn],wv[maxn],_ws[maxn]; int c0(char *r,int a,int b) { return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2]; } int c12(int k,char *r,int a,int b) { if(k==2) return r[a]<r[b] || r[a]==r[b] && c12(1,r,a+1,b+1); else return r[a]<r[b] || r[a]==r[b] && wv[a+1]<wv[b+1]; } void sort(char *r,int *a,int *b,int n,int m) { int i; for(i=0;i<n;i++) wv[i]=r[a[i]]; for(i=0;i<m;i++) _ws[i]=0; for(i=0;i<n;i++) _ws[wv[i]]++; for(i=1;i<m;i++) _ws[i]+=_ws[i-1]; for(i=n-1;i>=0;i--) b[--_ws[wv[i]]]=a[i]; return; } void dc3(char *r,int *sa,int n,int m) { int i,j,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p; char *rn=r+n; r =r[n+1]=0; for(i=0;i<n;i++) if(i%3!=0) wa[tbc++]=i; sort(r+2,wa,wb,tbc,m); sort(r+1,wb,wa,tbc,m); sort(r,wa,wb,tbc,m); for(p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++) rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++; if(p<tbc) dc3(rn,san,tbc,p); else for(i=0;i<tbc;i++) san[rn[i]]=i; for(i=0;i<tbc;i++) if(san[i]<tb) wb[ta++]=san[i]*3; if(n%3==1) wb[ta++]=n-1; sort(r,wb,wa,ta,m); for(i=0;i<tbc;i++) wv[wb[i]=G(san[i])]=i; for(i=0,j=0,p=0;i<ta && j<tbc;p++) sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++]; for(;i<ta;p++) sa[p]=wa[i++]; for(;j<tbc;p++) sa[p]=wb[j++]; return; } int _rank[maxn],_height[maxn]; void cal_height(char *r,int *sa,int n) { int i; for(i=1;i<=n;i++) _rank[sa[i]]=i; return; } char r[maxn],rt[maxn]; int sa[maxn]; void _print(int ans1,int ans2,int n) { int t1=ans1; int t2=ans2; t2+=n; for(int i=0;i<n;i++){ if(rt[t1]>rt[t2]) { printf("%d 0\n",ans1+1); return ; } if(rt[t1]<rt[t2]) { printf("%d 1\n",ans2+1); return ; } t1++; t2--; } if(ans1<ans2) printf("%d 0\n",ans1+1); else if(ans2<ans1) printf("%d 1\n",ans2+1); else printf("%d 0\n",ans1+1); } int main() { int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); scanf("%s",r); for(int i=0;i<n;i++) { r[i+n]=r[i]; rt[i]=rt[i+n]=r[i]; } r[n+n]=0; dc3(r,sa,n+n+1,200); cal_height(r,sa,n+n); // for(int i=0;i<n+n;i++) // printf("1--%d\n",_rank[i]); int ans1=0; for(int i=1;i<n;i++) { if(_rank[i]>_rank[ans1]) ans1=i; } for(int i=0;i<n;i++) { r[i]=rt[n-i-1]; r[i+n]=rt[n-i-1]; } r[n+n]='z'+1; dc3(r,sa,n+n+1,200); cal_height(r,sa,n+n); int ans2=0; for(int i=1;i<n;i++) { if(_rank[i]>_rank[ans2]) ans2=i; } ans2=n-1-ans2; _print(ans1,ans2,n); // printf("%d %d\n",ans1,ans2); // for(int i=0;i<n+n;i++) // printf("2--%d\n",_rank[i]); } return 0; }
相关文章推荐
- Python3的tcp socket接收不定长数据包接收到的数据不全。
- http错误码大全
- iOS9网络适配
- Android访问网络,HttpURLConnection还是HttpClient?
- 经典C++库 http://hereson.iteye.com/blog/200799
- 获取网络连接的实例
- java发送http的get、post请求
- 使用Fiddler监听Java HttpURLConnection请求的小技巧
- Android连接网络
- 由于使用 xfire/HttpMethod 造成Socket连接池满的问题及解决办法
- poj 1149 PIGS(网络流 BFS 标号法)(困难)
- HBase的ACID http://hbase.apache.org/acid-semantics.html
- android-async-http源码解读(二)
- Android基础入门教程——7.6.3 基于TCP协议的Socket通信(2)
- 中国移动OnetNet云平台 使用WIFI模块ESP8266 TCP非透传模式传输数据流步骤
- CAPI HTTP服务搭建(文件在本机)
- linux 模拟http请求
- 使用Loadrunner进行http接口压力测试
- 中国移动OnetNet云平台 使用WIFI模块ESP8266 TCP透传模式传输数据流步骤
- vim基本命令笔记