POJ - 3294 Life Forms

2023-12-22 08:49
文章标签 poj life forms 3294

本文主要是介绍POJ - 3294 Life Forms,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.题面

http://poj.org/problem?id=3294

2.题意

给你n个字符串,希望你求出一个长度最长的子串s,s在至少n/2个字符串中出现过,

3.思路

将所有的数字连在一起后使用后缀数组,二分答案

第二种方法也是先用后缀数组处理,后面使用一个尺取法

二分   800+ms

尺取法  1200+ms

我觉得set的常数产生了很大的影响

4.代码

二分代码

/*****************************************************************> File Name: Cpp_Acm.cpp> Author: Uncle_Sugar> Mail: uncle_sugar@qq.com> Created Time: 2016年08月01日 星期一 18时50分27秒
*****************************************************************/
# include <cstdio>
# include <cstring>
# include <cctype>
# include <cmath>
# include <cstdlib>
# include <climits>
# include <iostream>
# include <iomanip>
# include <set>
# include <map>
# include <vector>
# include <stack>
# include <queue>
# include <algorithm>
using namespace std;# define rep(i,a,b) for (i=a;i<=b;i++)
# define rrep(i,a,b) for (i=b;i>=a;i--)template<class T>void PrintArray(T* first,T* last,char delim=' '){ for (;first!=last;first++) cout << *first << (first+1==last?'\n':delim); 
}const int debug = 1;
const int size  = 1000 + 300000 ; 
const int INF = INT_MAX>>1;
typedef long long ll;const int MAXN = 500000 + 1000;  
#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*3],wb[MAXN*3],wv[MAXN*3],wss[MAXN*3];  
int c0(int *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,int *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(int *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++)wss[i] = 0;  for(i = 0;i < n;i++)wss[wv[i]]++;  for(i = 1;i < m;i++)wss[i] += wss[i-1];  for(i = n-1;i >= 0;i--)  b[--wss[wv[i]]] = a[i];  
}  
void dc3(int *r,int *sa,int n,int m)  
{  int i, j, *rn = r + n;  int *san = sa + n, ta = 0, tb = (n+1)/3, tbc = 0, p;  r[n] = 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++];  
}  
//str和sa也要三倍  
void da(int str[],int sa[],int rank[],int height[],int n,int m)  
{  for(int i = n;i < n*3;i++)  str[i] = 0;  dc3(str, sa, n+1, m);  int i,j,k = 0;  for(i = 0;i <= n;i++)rank[sa[i]] = i;  for(i = 0;i < n; i++)  {  if(k) k--;  j = sa[rank[i]-1];  while(str[i+k] == str[j+k]) k++;  height[rank[i]] = k;  }  
}  
int sa[size],rrank[size],height[size];  int n,k;      int str[size],len; 
int zone[size];
char s[size];int vis[200];
queue<int> que;
bool isok(int ll){memset(vis,0,sizeof(vis));while (!que.empty()) que.pop();que.push(zone[sa[1]]);vis[zone[sa[1]]] = 1;//# for (int i=1;i<=n;i++){//# cout << height[i] << (i==n?'\n':' ');//# }//# cout << endl;for (int i=2;i<=len;i++){//# cout << "height " << i << " " << height[i] << endl;if (height[i]>=ll){if (vis[zone[sa[i]]]==0){que.push(zone[sa[i]]);vis[zone[sa[i]]] = 1;}}else {//# cout << "que.size = " << que.size() << endl; if (que.size()>n/2) return true;while (!que.empty()){vis[que.front()] = 0;que.pop();}que.push(zone[sa[i]]);vis[zone[sa[i]]] = 1;}}if (que.size()>n/2)return true;return false;
}void Debug(int n){for (int i=1;i<=n;i++){cout << "*" << i << "*\t" << height[i] << "\t" << zone[sa[i]] << '\t';PrintArray(str+sa[i],str+n,'\t');}
}int main()  
{  int i,j;  int ncase = 0;while (~scanf("%d",&n)){  if (!n) break;if (ncase++) cout << endl;len = 0;for (i=0;i<n;i++){scanf("%s",s);	for (j=0;s[j];j++){str[len] = s[j] + 200;zone[len] = i;len++;}if (i==n-1){str[len] = 0;}else {zone[len] = i;str[len++] = 1+i;}}//# void da(char str[],int sa[],int rrank[],int height[],int n,int m){  da(str,sa,rrank,height,len,500);int l = 0,r = len+1;while (l < r-1){int mid = l+r>>1;if (isok(mid)){l = mid;}else {r = mid;}}//# cout << "l = " << l << endl;//# Debug(len);if (l==0){cout << "?" << endl;}else {memset(vis,0,sizeof(vis));while (!que.empty()) que.pop();que.push(zone[sa[1]]);vis[zone[sa[1]]] = 1;for (i=1;i<=len;i++){if (height[i]>=l){if (vis[zone[sa[i]]]==0){que.push(zone[sa[i]]);vis[zone[sa[i]]] = 1;}}else {if (que.size()>n/2){for (j=sa[i-1];j<sa[i-1]+l;j++){cout << char(str[j]-200);}cout << endl;}while (!que.empty()){vis[que.front()] = 0;	que.pop();}que.push(zone[sa[i]]);vis[zone[sa[i]]] = 1;}}if (que.size()>n/2){for (j=sa[i-1];j<sa[i-1]+l;j++){cout << char(str[j]-200);}cout << endl;}}}return 0;  
}


第二种思路

/***************************************************************** > File Name: Cpp_Acm.cpp > Author: Uncle_Sugar > Mail: uncle_sugar@qq.com > Created Time: 2016年08月01日 星期一 18时50分27秒 *****************************************************************/  
# include <cstdio>  
# include <cstring>  
# include <cctype>  
# include <cmath>  
# include <cstdlib>  
# include <climits>  
# include <iostream>  
# include <iomanip>  
# include <set>  
# include <map>  
# include <vector>  
# include <stack>  
# include <queue>  
# include <algorithm>  
using namespace std;  # define rep(i,a,b) for (i=a;i<=b;i++)  
# define rrep(i,a,b) for (i=b;i>=a;i--)  template<class T>void PrintArray(T* first,T* last,char delim=' '){   for (;first!=last;first++) cout << *first << (first+1==last?'\n':delim);   
}  const int debug = 1;  
const int size  = 1000 + 300000 ;   
const int INF = INT_MAX>>1;  
typedef long long ll;  const int MAXN = 500000 + 1000;    
#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*3],wb[MAXN*3],wv[MAXN*3],wss[MAXN*3];    
int c0(int *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,int *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(int *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++)wss[i] = 0;    for(i = 0;i < n;i++)wss[wv[i]]++;    for(i = 1;i < m;i++)wss[i] += wss[i-1];    for(i = n-1;i >= 0;i--)    b[--wss[wv[i]]] = a[i];    
}    
void dc3(int *r,int *sa,int n,int m)    
{    int i, j, *rn = r + n;    int *san = sa + n, ta = 0, tb = (n+1)/3, tbc = 0, p;    r[n] = 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++];    
}    
//str和sa也要三倍    
void da(int str[],int sa[],int rank[],int height[],int n,int m)    
{    for(int i = n;i < n*3;i++)    str[i] = 0;    dc3(str, sa, n+1, m);    int i,j,k = 0;    for(i = 0;i <= n;i++)rank[sa[i]] = i;    for(i = 0;i < n; i++)    {    if(k) k--;    j = sa[rank[i]-1];    while(str[i+k] == str[j+k]) k++;    height[rank[i]] = k;    }    
}    
int sa[size],rrank[size],height[size];    int n,k;        int str[size],len;   
int zone[size];  
char s[size];  int vis[200];  
set<int> st;void Debug(int n){  for (int i=1;i<=n;i++){  cout << "*" << i << "*\t" << height[i] << "\t" << zone[sa[i]] << '\t';  PrintArray(str+sa[i],str+n,'\t');  }  
}  struct Comper{  int operator () (const int x,const int y){  if (height[x]==height[y])return x<y?y:x;return height[x] < height[y]?x:y;  }  
}comp;  
/* * 这种情况下会返回最小值的下标 */  const int MAXRMQSIZE = 110000;  struct RMQ{  int dp[MAXRMQSIZE][25];  int mm[MAXRMQSIZE];  //初始化RMQ, b数组下标从1开始,从0开始简单修改  RMQ(){}  void initRMQ(int n){  mm[0] = -1;  for(int i = 1; i <= n;i++){  mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1];  dp[i][0] = i;  }  for(int j = 1; j <= mm[n];j++)  for(int i = 1;i + (1<<j) -1 <= n;i++)  dp[i][j] = comp(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);  }  //查询最大值  int rmq(int x,int y){  if (x > y)swap(x,y);int k = mm[y-x+1];  return comp(dp[x][k],dp[y-(1<<k)+1][k]);  }  
};  
RMQ rmqq;int ans = 0;
vector<int> anspos;
int main()    
{    int i,j;    int ncase = 0;  while (~scanf("%d",&n)){    if (!n) break;  if (ncase++) cout << endl;  len = 0;  for (i=0;i<n;i++){  scanf("%s",s);    for (j=0;s[j];j++){  str[len] = s[j] + 200;  zone[len] = i;  len++;  }  if (i==n-1){  str[len] = 0;  }  else {  zone[len] = i;  str[len++] = 1+i;  }  }  //# void da(char str[],int sa[],int rrank[],int height[],int n,int m){    da(str,sa,rrank,height,len,500);  //# Debug(len);  int left,right;st.clear();anspos.clear();memset(vis,0,sizeof(vis));rmqq.initRMQ(len);ans = 0;for (left=right=1;left<=len;left++){while (st.size() <= n/2 && right<=len){if (vis[zone[sa[right]]]++==0){st.insert(zone[sa[right]]);	}right++;}if (st.size() <= n/2) break;//# cout << "left " << left << " right " << right ;int k = rmqq.rmq(left+1,right-1);//# cout << "left + 1 " << left+1 << " right-1 " << right-1 << " " << height[k]<< endl;if (height[k] > ans){ans = height[k];anspos.clear();anspos.push_back(k);}else if (height[k] == ans){if (anspos.empty()||height[rmqq.rmq(anspos.back(),k)] < ans)anspos.push_back(k);}if (--vis[zone[sa[left]]]==0){st.erase(zone[sa[left]]);}}if (ans==0){putchar('?');putchar('\n');}else{for (i=0;i<anspos.size();i++){int loc = sa[anspos[i]];for (j=loc;j<loc+ans;j++){putchar(char(str[j] - 200));}putchar('\n');}}}return 0;    
}



这篇关于POJ - 3294 Life Forms的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/523326

相关文章

使用Python实现生命之轮Wheel of life效果

《使用Python实现生命之轮Wheeloflife效果》生命之轮Wheeloflife这一概念最初由SuccessMotivation®Institute,Inc.的创始人PaulJ.Meyer... 最近看一个生命之轮的视频,让我们珍惜时间,因为一生是有限的。使用python创建生命倒计时图表,珍惜时间

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

poj 1511 Invitation Cards(spfa最短路)

题意是给你点与点之间的距离,求来回到点1的最短路中的边权和。 因为边很大,不能用原来的dijkstra什么的,所以用spfa来做。并且注意要用long long int 来存储。 稍微改了一下学长的模板。 stack stl 实现代码: #include<stdio.h>#include<stack>using namespace std;const int M

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D

poj 1502 MPI Maelstrom(单源最短路dijkstra)

题目真是长得头疼,好多生词,给跪。 没啥好说的,英语大水逼。 借助字典尝试翻译了一下,水逼直译求不喷 Description: BIT他们的超级计算机最近交货了。(定语秀了一堆词汇那就省略吧再见) Valentine McKee的研究顾问Jack Swigert,要她来测试一下这个系统。 Valentine告诉Swigert:“因为阿波罗是一个分布式共享内存的机器,所以它的内存访问

uva 10061 How many zero's and how many digits ?(不同进制阶乘末尾几个0)+poj 1401

题意是求在base进制下的 n!的结果有几位数,末尾有几个0。 想起刚开始的时候做的一道10进制下的n阶乘末尾有几个零,以及之前有做过的一道n阶乘的位数。 当时都是在10进制下的。 10进制下的做法是: 1. n阶位数:直接 lg(n!)就是得数的位数。 2. n阶末尾0的个数:由于2 * 5 将会在得数中以0的形式存在,所以计算2或者计算5,由于因子中出现5必然出现2,所以直接一