Contest-hunter 暑假送温暖 SRM08

01-07都没写...然后突然来写貌似有点突兀啊...不管了,难得前排记录一下...

吐槽一下赛制...不得不说很强... cf 套oi...很创新...不过还是兹磁ACM或者CF

A-1

数据才2<=n<=3 ...但是一眼过去就先打了个dfs 。

所以这个应该是A-2的题解。

a1应该打表就好了...

A-2

这个就是dfs啊...

搜索出所有的s串的子集,然后暴力判一下...

var s:string;
    a:array[0..100]of string;
    i,j:longint;
    tot,x:longint;
procedure dfs(dep,last:longint;t:string);
var i:longint;
begin
  if dep>1 then
  begin
    inc(tot);
    a[tot]:=t;
  end;
  for i:=last+1 to length(s) do
  dfs(dep+1,i,t+s[i]);
end;
begin
  readln(s);
  dfs(1,0,'');
  for i:=1 to tot do
  begin
    x:=0;
    for j:=1 to tot do
    if (a[i]=a[j])and(length(a[i])=length(a[j])) then inc(x);
    if x=2 then
    begin
      writeln('Y');
      exit;
    end;
  end;
  writeln('N');
end.
A-2

A-3

貌似因为数据随机...所以可以用rp卡... 对于n>10 很可能是"Y" 所以A-2再加个特判可以水...

正解不会QAQ...会了再来补

悄悄咪咪的去看了HR的代码...自己推敲了一波基本上懂了

对于一个01串

很显然 如果 0 或 1 有且仅有两个 辣么就是 “Y” 这时 T 串为 0 或 1

当然还有 其他可能为“Y”。

辣么什么时候捏

就是 比如

   0110101

  这个串看起来好像很一般,但他就是“Y”。

   他的T就是010101

   因此我萌就可以发现了 如果s串中存在有且仅有2个连续1 或 0 辣么就可以是“Y”。

   所以暴力判一下就好了...

  ORZ HR!

var
   c:array['0'..'1']of longint;
   s:ansistring;
   n,i:longint; 
begin
  readln(s);
  n:=length(s);
  for i:=1 to n do
  inc(c[s[i]]);
  if (c['0']=2)or(c['1']=2) then
  begin
    writeln('Y');
    exit;
  end;
  if n=2 then
  begin
    writeln('N');
    exit;
  end;
  if (s[1]=s[2])and(s[2]<>s[3]) then
  begin
    writeln('Y');
    exit;
  end;
  if (s[n]=s[n-1])and(s[n]<>s[n-2]) then
  begin
    writeln('Y');
    exit;
  end;
  for i:=3 to n-1 do
  if (s[i]=s[i-1])and(s[i]<>s[i-2])and(s[i]<>s[i+1]) then
  begin
    writeln('Y');
    exit;
  end;
  writeln('N');
end.
A-3

B-1

很明显用dfs水...

搜索出所有子序列,然后暴力判...

var n,m:longint;
    a,b,c:array[0..100]of longint;
    ans:int64;
    i:longint;
procedure dfs(dep,last:longint);
var i,j:longint;
    x:boolean;
begin
  if dep=m then
  begin
    x:=true;
    for j:=1 to m do
    if a[c[j]]+b[j]<a[c[j-1]]+b[j-1] then
    begin
      x:=false;
      break;
    end;
    if x then inc(ans);
    exit;
  end;
  for i:=last+1 to n do
  begin
    c[dep+1]:=i;
    dfs(dep+1,i);
  end;
end;
begin
  read(n,m);
  for i:=1 to n do
  read(a[i]);
  for i:=1 to m do
  read(b[i]);
  dfs(0,0);
  writeln(ans);
end.
B-1

B-2

不擅长dp啊QAQ

本来想不看代码自己手动推的...

写完之后一直炸...只能悄悄咪咪的去看葱神代码了...

然后发现貌似差不多啊...改成一样之后还是炸...(最后是一个sb问题)

然后我再改回原来代码就过辣!

思路是酱紫的:  设f[i,j] 表示 c数列以 i  结尾,长度为 j 且满足题目要求的c数列的方案数...

辣么肿么转移捏...

推了一下大概是酱紫的:   f[i,j]+=f[k,j-1]  1<=k<=i 且满足 a[i]+b[j]>=a[k]+b[j-1]

这个方程的意思就是说 因为考虑前一位,所以就通过j-1 长度来转移 j ...然后以 i 结尾,所以对于前面的1~(i-1) 都可以进行转移 然后在判是否满足条件

然后初始化就是 f[i,1]=1 因为 对于任意长度为1 的序列方案数就是1

var
  n,m:longint;
  a,b:array[0..10000]of longint;
  i,j,k:longint;
  f:array[0..500,0..500]of longint;
  ans:int64;
begin
  read(n,m);
  for i:=1 to n do
  read(a[i]);
  for i:=1 to m do
  read(b[i]);
  for i:=1 to n do
  f[i,1]:=1;
  for i:=1 to n do
  begin
    for j:=2 to m do
    for k:=1 to i-1 do
    if a[i]+b[j]>=a[k]+b[j-1] then
    f[i,j]:=(f[i,j]+f[k,j-1]) mod 1000000007;
  end;
  for i:=1 to n do
  ans:=(ans+f[i,m]) mod 1000000007;
  writeln(ans);
end.
B-2

B-3

到处搜刮题解QAQ...太笨不懂啊QAQ...

大概就是用个树状数组来优化...

具体优化不会QAQ...

貌似B-3数据没弄啊...悄悄咪咪去交个B-2

C-1

发现n比较小,所以floyd跑一下,然后暴力判k个特殊点...这样就水过去?

比赛时KPM提醒了一下有重边...所以记得去重边,就加个min而已...

var n,m,q:longint;
    i,j,k:longint;
    x,y,z:longint;
    c:array[0..1000]of longint;
    dist:array[0..350,0..350]of longint;
    min:longint;
function mn(a,b:longint):longint;
begin
  if a<b then exit(a) else exit(b);
end;
begin
  read(n,m,q);
  for i:=1 to q do
  read(c[i]);
  for i:=1 to n do
  for j:=1 to n do
  dist[i,j]:=1 << 25;
  for i:=1 to m do
  begin
    read(x,y,z);
    dist[x,y]:=mn(dist[x,y],z);
    dist[y,x]:=dist[x,y];
  end;
  for k:=1 to n do
  for i:=1 to n do
  for j:=1 to n do
  if dist[i,k]+dist[k,j]<dist[i,j] then
    dist[i,j]:=dist[i,k]+dist[k,j];
    min:=maxlongint;
  for i:=1 to q do
  for j:=1 to q do
  if (i<>j) then
    if dist[c[i],c[j]]<min then min:=dist[c[i],c[j]];
  writeln(min);
end.
C-1

C-2

发现n变大了...但是k很小,所以可以跑k次最短路

只会spfa...QAQ...

对于每个特殊点为s跑spfa,然后在暴力更新答案

n比较大所以记得要邻接表,邻接矩阵会炸...

然后边记得开两倍,因为是双向的...貌似挺多在这re了...

type
  node=record
      y,z:longint;
      next:longint;
  end;
var  e:array[0..200050]of node;
     i,j:longint;
     dist,first,c:array[0..100050]of longint;
     x,y,z:longint;
     q:array[0..1000050]of longint;
     v:array[0..100050]of boolean;
     tot:longint;
     n,m,p:longint;
     min:longint;
procedure adde(x,y,z:longint);
begin
  e[tot].next:=first[x];
  e[tot].y:=y;
  e[tot].z:=z;
  first[x]:=tot;
  inc(tot);
end;
procedure spfa(s:longint);
var head,tail:longint;
    i,now,y:longint;
begin
  head:=1;
  tail:=1;
  for i:=1 to n do
  begin
    dist[i]:=1 << 25;
    v[i]:=false;
  end;
  q[1]:=s;
  v[s]:=true;
  dist[s]:=0;
  while head<=tail do
  begin
    now:=q[head];
    i:=first[now];
    while i<>-1 do
    begin
      y:=e[i].y;
      if dist[y]>dist[now]+e[i].z then
      begin
        dist[y]:=dist[now]+e[i].z;
        if not v[y] then
        begin
          inc(tail);
          q[tail]:=y;
          v[y]:=true;
        end;
      end;
      i:=e[i].next;
    end;
    inc(head);
    v[now]:=false;
  end;
end;
begin
  read(n,m,p);
  for i:=1 to p do
  read(c[i]);
  for i:=1 to n do
  first[i]:=-1;
  for i:=1 to m do
  begin
    read(x,y,z);
    adde(x,y,z);
    adde(y,x,z)
  end;
  min:=maxlongint;
  for i:=1 to p do
  begin
    spfa(c[i]);
    for j:=1 to p do
    if (i<>j)and(dist[c[j]]<min) then min:=dist[c[j]];
  end;
  writeln(min);
end.
C-2

C-3

还是搜刮题解没看懂...貌似是dijkstra...没学QAQ

bfs貌似也行...但是看不懂...

TJM的神奇分集合也不是很懂...

实在不会啊QAQ 

先水这一点...然后去补题了...

posted @ 2017-07-27 12:33  Bunnycxk  阅读(151)  评论(0编辑  收藏  举报