2015-2016 下半学期 第二周 训练(2)
来源:互联网 发布:手立视高清网络摄像机 编辑:程序博客网 时间:2024/05/19 19:15
1、hdu3336
题意:相同前缀的次数和。
题解:利用了KMP中next数组的含义,从j直接跳到next[j]的原因是next[j]~j中不会再有和1~j中的相同前缀。
next[i]表示了模式串p[1~i-1]中最大的相同的前缀和后缀的长度。
PS:关于KMP的具体讲解 请看这篇文章,http://blog.csdn.net/v_july_v/article/details/7041827
代码:
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>#include<queue>#include<vector>#include<set>#include<stack>#include<map>#include<ctime>#include<bitset>#define LL long long#define db double#define EPS 1e-15#define inf 1e8using namespace std;char s[2000000];int nxt[2000000];int MOD=10007;void get(){ int i=0,j=-1; nxt[0]=-1; while (s[i]!='\0'){ if (j==-1 || s[j]==s[i]){ i++,j++; nxt[i]=j; } else j=nxt[j]; }}int main(){ int T,len,ans; scanf("%d",&T); while (T--){ memset(nxt,0,sizeof(nxt)); scanf("%d %s",&len,s); get(); ans=len; for (int i=1;i<=len;i++){ int tmp=nxt[i]; while (tmp){ ans=(ans+1)%MOD; tmp=nxt[tmp]; } } printf("%d\n",ans); } return 0;}
2、hdu4763
题意:在所给字符串中寻找E···E···E形式的最长E。
题解:根据next数组的意义next[len]满足的串形式首尾相同,即在剩下的串种寻找相同的子串,可以适当缩小子串长度。
代码:
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>#include<queue>#include<vector>#include<set>#include<stack>#include<map>#include<ctime>#include<bitset>#define LL long long#define db double#define EPS 1e-15#define inf 1e8using namespace std;const int MAXN = 1000100;char str[MAXN];char tmp[MAXN];int nextval[MAXN];int len;void get(char *s,int lenth){ int i=0,j=-1; nextval[0]=-1; while (i<lenth){ if (j==-1 || s[i]==s[j]){ i++; j++; if(s[i]!=s[j]) nextval[i]=j; else nextval[i]=nextval[j]; } else j=nextval[j]; } return ;}bool KMP(char *t,char *s,int lenth,int lenn){ int i=0,j=0; while (j<lenn){ if (i==-1 || s[j]==t[i]){ i++; j++; if (i==lenth) return 1; } else i=nextval[i]; } return 0;}int main(){ int T; scanf("%d",&T); while (T--){ scanf("%s",str); len=strlen(str); get(str,len); int ans=nextval[len]; while (ans>len/3) ans=nextval[ans]; while (ans>0){ if (KMP(str,&str[ans],ans,len-ans-ans)) break; ans=nextval[ans]; } if (ans<0) printf("%d\n",len/3); else printf("%d\n",ans); } return 0;}
3、hdu2594
题意:给出字符串A,B,求A的前缀和B的后缀相同的最大长度。
题解:两个字符串中间添加一个不会出现的特殊符号,然后对合并后的串求一下next。
代码:
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>#include<queue>#include<vector>#include<set>#include<stack>#include<map>#include<ctime>#include<bitset>#define LL long long#define db double#define EPS 1e-15#define inf 1e8using namespace std;void get(char *x,int m,int nxt[]){ int i=0,j=-1; nxt[0]=-1; while (i<m){ if (j==-1 || x[i]==x[j]){ i++,j++; if (x[i]!=x[j]) nxt[i]=j; else nxt[i]=nxt[j]; } else j=nxt[j]; } return ;}int nxt[100010];int main(){ char str1[100010]; char str2[50010]; while (~(scanf("%s%s", str1, str2))){ int tmp1=strlen(str1); str1[tmp1]='&'; str1[tmp1+1]='\0'; strcat(str1,str2); int tmp=strlen(str1); memset(nxt,0,sizeof(nxt)); get(str1,tmp,nxt); if (nxt[tmp]){ for (int i=0;i<nxt[tmp];i++){ printf("%c",str1[i]); } printf(" "); printf("%d\n",nxt[tmp]); } else printf("%d\n",nxt[tmp]); } return 0;}
4、hdu3746
题意:字符串中任意字符必须以“段“的形式重覆两次,问最少需要添加几个字符。
题解:next数组的意义就是代表模式串中必须是成段对称,所以求个next然后根据重复的段长度求个%。
代码:
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>#include<queue>#include<vector>#include<set>#include<stack>#include<map>#include<ctime>#include<bitset>#define LL long long#define db double#define EPS 1e-15#define inf 1e8using namespace std;const int N = 100002;char str[N];int nxt[N];void get(int len){ int i; int j=0; for(nxt[1]=0,i=2;i<=len;i++) { while(j && str[j+1]!=str[i]){ j=nxt[j]; } if(str[j+1]==str[i]){ j++; } nxt[i]=j; }}int main(){ int t; scanf("%d",&t); while(t--) { scanf("%s", str + 1); int len = strlen(str + 1); get(len); int x =len-nxt[len]; if(len%x==0 && len!=x){ printf("0\n"); } else{ printf("%d\n",x-nxt[len]%x); } } return 0;}
5、poj1151
ACdreamer有一种非线段树的写法,不过分析了复杂度发现是递归的n^3复杂度。 在这里补上线段树的nlogn写法。
题意:求矩形面积并。
题解:扫描线+线段树。将矩形的竖边删掉,剩下的横匾按照y值排序,由小到大,每个矩形下端的边称之为入边,标记为+1,上端的边称之为出边,标记为-1。每个node节点维护当前这个区间内的被覆盖的长度,被标记的大小,即(+1-1+1-1)这种形式的和,以确定扫到了哪里。从下往上扫的时候,遇到+1则更新被覆盖长度,遇到-1则相乘并累加。
代码:
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>#include<queue>#include<vector>#include<set>#include<stack>#include<map>#include<ctime>#include<bitset>#define LL long long#define db double#define EPS 1e-15#define inf 1e8using namespace std;#define lz 2*u,l,mid#define rz 2*u+1,mid+1,rconst int maxn=4222;db sum[maxn];db flag[maxn];db X[maxn];struct Node{ db lx, rx, y; int s; Node(){}; Node(db lx_,db rx_,db y_,db s_){ lx=lx_, rx=rx_, y=y_, s=s_; } bool operator <(const Node &S) const{ return y<S.y; }}line[maxn];int find(db tmp,int n){ int l=1,r=n,mid; while (l<=r){ mid=(l+r)>>1; if (X[mid]==tmp) return mid; else if(X[mid]<tmp) l=mid+1; else r=mid-1; }}void pushup(int u ,int l,int r){ if (flag[u]) sum[u]=X[r+1]-X[l]; else if (l==r) sum[u]=0; else sum[u]=sum[2*u]+sum[2*u+1];}void update(int u,int l,int r,int tl,int tr,int c){ if (tl<=l && r<=tr){ flag[u]+=c; pushup(u,l,r); return ; } int mid=(l+r)>>1; if (tr<=mid) update(lz,tl,tr,c); else if (tl>mid) update(rz,tl,tr,c); else { update(lz,tl,mid,c); update(rz,mid+1,tr,c); } pushup(u,l,r);}int main(){ int n,cas=0; while (~scanf("%d",&n),n){ int num=0; memset(flag,0,sizeof(flag)); memset(sum,0,sizeof(sum)); for (int i=1;i<=n;i++){ db x1,x2,y1,y2; scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); line[num++]=Node(x1,x2,y1,1); X[num]=x1; line[num++]=Node(x1,x2,y2,-1); X[num]=x2; } sort(X+1,X+1+num); sort(line+1,line+1+num); int k=1; for (int i=2;i<=num;i++) if (X[i]!=X[i+1]) X[++k]=X[i]; db ans=0; for (int i=1;i<num;i++){ int l=find(line[i].lx,k); int r=find(line[i].rx,k)-1; update(1,1,k,l,r,line[i].s); ans+=sum[1]*(line[i+1].y-line[i].y); } printf("Test case #%d\n",++cas); printf("Total explored area: %.2f\n\n",ans); } return 0;}
6、poj1177
题意:求矩形周长并
{待补)
- 2015-2016 下半学期 第二周 训练(2)
- 2015-2016 下半学期 第二周 训练
- 2015-2016 下半学期 第八周 训练(2)
- 2015-2016 下半学期 第三周 训练
- 2015-2016 下半学期 第五周 训练
- 2015-2016 下半学期 第六周 训练
- 2015-2016 下半学期 第八周 训练
- 2015-2016 下半学期 第十周 训练
- 2015-2016 下半学期 第一周 训练
- 2015-2016 下半学期 第四周 训练
- 下半学期第二周实验报告
- 第二学期第六周项目2
- 大一下半学期
- 第二学期第二周项目一
- 第二学期第二周项目二
- 2016-2017学年第二学期C++第三章(2)
- 2016-2017学年第二学期C++第四章(2)
- 2016-2017学年第二学期C++第五章(2)
- 15个数的大小
- python异常处理基础笔记
- 基于TMS320F28335的运动控制器--开发与调试记录2
- memcached全面剖析--2.理解memcached的内存存储
- Spinner相互监听关联
- 2015-2016 下半学期 第二周 训练(2)
- Jenkins+Maven+SVN快速搭建持续集成环境(转)
- STL-set
- Android中的UI刷新
- 第三周项目三(2)-输出空心三角
- Problem Q
- java连接mysql并向其中插入数据中文乱码问题
- excel导入mysql(用PHP-ExcelReader 方法),日期时间出错的处理办法
- leetcode 145. Binary Tree Postorder Traversal