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-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.
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-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-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-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-3
还是搜刮题解没看懂...貌似是dijkstra...没学QAQ
bfs貌似也行...但是看不懂...
TJM的神奇分集合也不是很懂...
实在不会啊QAQ
先水这一点...然后去补题了...