1.15三道水题题解

来源:互联网 发布:诊疗指南软件下载 编辑:程序博客网 时间:2024/05/18 20:12

第一题:

给定一个由小写字母组成的字符串,寻找包含“agnus”(羔羊)的子串的个数。注意:当且仅当两个子串的起始位置和终点不同时,这两个子串属于不同的子串。

Sample Input

agnusbgnus

Sample Output

6【样例解释】    6个子串分别是:agnus、agnusb、agnusbg、agnusbgn、agnusbgnu、agnusbgnus。

Data Constraint

对于 40%的数据,字符串长度<=1000
对于 100%的数据,字符串长度<=30000

嗯,水题。统计每个agnus的起点和终点,然后累加结果即可。

代码:(跑了4ms居然。。。好慢好慢)

var n,i,j,k,t:longint;s:ansistring;ans:int64;l,r:array[0..1000000]of longint;begin  {assign(input,'agnus.in');  assign(output,'agnus.out');  reset(input);  rewrite(output);}  readln(s);  n:=length(s);  for i:=1 to n-4 do if copy(s,i,5)='agnus' then begin    inc(t);    l[t]:=i;    r[t]:=i+4;  end;  for i:=1 to t do ans:=ans+(l[i]-l[i-1])*(n+1-r[i]);  writeln(ans);  close(input);  close(output);end.
第二题:

n个天使排成一条直线,某些天使之间需要互相联系,他们之间的通讯可以通过黑白两种通道中的一种;所有通道必须在直线同侧(另一侧是地面);为了保证通讯效率,同种颜色的所有通道之间不能相交。请计算能否建立这种通讯方案。

Sample Input

17 51 32 73 47 46 5

Sample Output

sane
【提示】
当两条线路有一对相同的端点时,这两条线路不相交。
也就是说,对于线路(a,b)和线路(c,d)(a<b且c<d),当且仅当a<c<b<d或者c<a<d<b时这两条线路相交。

Data Constraint

对于 20%的数据,1<=n<=50,1<=m<=15
对于 50%的数据,1<=n<=1000,1<=m<=300
对于 100%的数据,1<=n<=5000,1<=m<=1000,1<=T<=10,1<=a<=n,1<=b<=n
数据保证每对(a,b)不重复,且a不等于b


正解是线段树,可是我不会打。但二分图染色和bfs也可以跑得很优美。

bfs每条边,给他上色,对于每一条与其相交的边染反色并加入队列,直到发生冲突或染色完成。

代码:(不加快排能过,加了快排快30ms)

var t,n,m,i,j,x,head,tail,u,k:longint;d,color,a,b:array[0..10001] of longint;flag:array[0..10011] of boolean;p:boolean;procedure ss(l,r:longint);var i,j,k,k1:longint;begin  i:=l;  j:=r;  k:=a[(l+r) div 2];  k1:=b[(l+r) div 2];  repeat    while (a[i]<k)or((a[i]=k)and(b[i]<k1)) do inc(i);    while (a[j]>k)or((a[j]=k)and(b[j]>k1)) do dec(j);    if i<=j then begin      a[0]:=a[i];      a[i]:=a[j];      a[j]:=a[0];      b[0]:=b[i];      b[i]:=b[j];      b[j]:=b[0];      inc(i);      dec(j);    end;  until i>j;  if i<r then ss(i,r);  if j>l then ss(l,j);end;begin  readln(t);  for k:=1 to t do begin    readln(n,m);    for i:=1 to m do begin      flag[i]:=false;      readln(a[i],b[i]);      if a[i]>b[i] then begin        x:=a[i];        a[i]:=b[i];        b[i]:=x;      end;    end;    ss(1,m);    p:=true;    for i:=1 to m do begin      if p=false then break;      if flag[i]=false then      begin        head:=0;        tail:=1;        d[1]:=i;        color[i]:=1;        while head<>tail do begin          if p=false then break;          head:=head+1;          u:=d[head];          flag[u]:=true;          for j:=1 to m do if ((a[j]<a[u])and(a[u]<b[j])and(b[j]<b[u]))or((a[u]<a[j])and(a[j]<b[u])and(b[u]<b[j])) then          if flag[j] then if color[j]=color[u] then begin            writeln('non');            p:=false;            break;          end else          else begin            tail:=tail+1;            color[j]:=color[u] mod 2+1;            d[tail]:=j;            flag[j]:=true;          end;          if p=false then break;        end;      end;    end;    if p then writeln('sane');  end;end.
第三题:

给定两个字符串a和b,我们可以定义一些操作:a*b为将字符串a和字符串b连接起来,比如a= "aoe",b= "jkw",那么a*b= "aoejkw"。进一步,我们可以有指数操作,a^0= "", a^1=a, a^2=a*a, a^n=a*(a^(n-1))=a*a*…*a (n个a)
现在给你一个字符串,你可以将它看成是a^n的形式,比如字符串"abababab",可以认为是"abab"^2, 也可以是"abababab"^1,还可以是"ab"^4。
现在问题是,给定的字符串,我们想让它变成a^n中的n达到最大,那么这个n最大是多少?例如:"abababab"最大的n是4。

Sample Input

3abcdeaaaaaaabababab

Sample Output

164

Data Constraint

30%的数据:字符串的长度≤1000;
100%的数据:字符串的长度≤1000000, m≤10,字符串内只含小写字母。

正解KMP算法,读入时按位判断,如果出现与当前找到的串有冲突的区域,加入截止到冲突区域的所有字符。
最快O(n),最慢O(2n)。
路边水法:求字符串长度的因数,在枚举因数,暴力判断。
貌似很优美的样子。
程序我就不给了。(KMP不会打的事实不能暴露)

还是很水的,抬一手!!!

0 0
原创粉丝点击