2017 国庆湖南 Day3
期望得分:100+30+60=190
实际得分:10+0+55=65
到了233 2是奇数位 或223 第2个2是偶数位就会223 、233 循环
#include<cstdio> #define N 1000001 using namespace std; char s[N+]; int main()
{
freopen("trans.in","r",stdin);
freopen("trans.out","w",stdout);
int n,k; bool ok;
while(scanf("%d%d",&n,&k)!=EOF)
{
scanf("%s",s+);
ok=false;
for(int i=;i<n;i++)
{
if(s[i]=='' && s[i+]=='')
{
k--;
if(s[i-]=='')
{
if(i&) s[i+]='';
else
{
for(int j=;j<i;j++) printf("%c",s[j]);
if(k&) printf("");
else printf("");
for(int j=i+;j<=n;j++) printf("%c",s[j]);
ok=true; break;
}
}
else if(s[i+]=='')
{
if(i&)
{
for(int j=;j<=i;j++) printf("%c",s[j]);
if(k&) printf("");
else printf("");
for(int j=i+;j<=n;j++) printf("%c",s[j]);
ok=true; break;
}
else s[i]='';
}
else
{
if(i&) s[i+]='';
else s[i]='';
}
if(!k) break;
}
}
if(!ok)
for(int i=;i<=n;i++) printf("%c",s[i]);
printf("\n");
}
return ;
}
注:不能向上走
因为蛇可以在一行内任意移动
他最终在一行内的移动范围是一段连续的区间
所以本题可以用区间DP解决
f[i][j][k] 表示 前i行,长度为j,从第k列离开第i行的最大得分
g[j][l][r] 表示当前长度为j,在区间[l,r]内移动,没有死亡的最大得分
开始时 ,对于每一个i,f[i][j][k]=g[j][k][k]=f[i-1][g-a[i][k]][k]+max(-a[i][k],0)
然后,区间由内向外更新, g[j][l][r]=max(g[j-a[i][l]][l+1][r]+a[i][l],g[j-a[i][r]][l][r-1]+a[i][r])
最后 更新f f[i][j][k]=max(g[j][l][r]) k∈[l,r]
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> #define N 201 using namespace std; int a[N][]; int f[N][N*][],g[N*][][]; bool can[N][]; void read(int &x)
{
x=; int f=; char c=getchar();
while(!isdigit(c)) { if(c=='-') f=-; c=getchar(); }
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
x*=f;
} int main()
{
freopen("snakevsblock.in","r",stdin);
freopen("snakevsblock.out","w",stdout);
int n,sum=;
read(n);
for(int i=;i<=n;i++)
for(int j=;j<=;j++)
{
read(a[i][j]);
if(a[i][j]>) sum+=a[i][j];
}
int m,x,y;
read(m);
for(int i=;i<=m;i++)
{
read(x); read(y);
can[x][y]=true;
}
memset(f,-,sizeof(f));
f[][][]=;
int r;
for(int i=;i<=n;i++)
{
memset(g,-,sizeof(g));
for(int j=;j<=sum;j++)
for(int k=;k<=;k++)
if(j-a[i][k]>=) f[i][j][k]=g[j][k][k]=f[i-][j-a[i][k]][k]+max(-a[i][k],);
for(int len=;len<=;len++)
for(int l=;l+len-<=;l++)
for(int j=;j<=sum;j++)
{
r=l+len-;
if(!can[i][l] && j-a[i][l]>=) g[j][l][r]=g[j-a[i][l]][l+][r]+max(-a[i][l],);
if(!can[i][r-] && j-a[i][r]>=) g[j][l][r]=max(g[j][l][r],g[j-a[i][r]][l][r-]+max(-a[i][r],));
for(int k=l;k<=r;k++) f[i][j][k]=max(f[i][j][k],g[j][l][r]);
}
}
int ans=;
for(int i=;i<=n;i++)
for(int j=;j<=sum;j++)
for(int k=;k<=;k++)
ans=max(ans,f[i][j][k]);
printf("%d",ans);
}
前 30%: O(2^n * n^3)
暴力枚举哪些站点损坏,floyd判断这些站点损坏时,测试的站点是否连通
另20%:O(nlogn+k)
问题转化为选择最少的点覆盖所有的线段
即留下最多的区间,使区间不相交
按右端点从小到大排序 ,删掉与当前区间有交的区间
另10%:分类讨论即可
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> using namespace std; #define N 100001 int n,m,k,out=1e6; int front[N],nxt[N<<],to[N<<],tot; int in[N],ans[N],id[N],cnt; int cut[N][]; bool con[][],f[]; int E[N][]; int vis[N],fa[N][]; struct node
{
int l,r,nl,nr;
}e[N*]; queue<int>q; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
} bool cmp(node p,node q)
{
return p.nr<q.nr;
} void bfs(int x)
{
id[x]=++cnt;
q.push(x);
int now;
while(!q.empty())
{
now=q.front(); q.pop();
for(int i=front[now];i;i=nxt[i])
if(!id[to[i]]) id[to[i]]=++cnt,q.push(to[i]);
}
} void solve2(int start)
{
bfs(start);
read(k);
for(int i=;i<=k;i++)
{
read(e[i].l),read(e[i].r);
e[i].nl=id[e[i].l];
e[i].nr=id[e[i].r];
if(e[i].nl>e[i].nr) swap(e[i].l,e[i].r),swap(e[i].nl,e[i].nr);
}
sort(e+,e+k+,cmp);
int sum=,last=;
for(int i=;i<=k;i++)
if(e[i].nl>last) last=e[i].nr,ans[++sum]=e[i].r;
printf("%d\n",sum);
for(int i=;i<=sum;i++) printf("%d ",ans[i]);
} void judge(int sum)
{
memset(con,false,sizeof(con));
for(int i=;i<=n;i++) if(!f[i]) con[i][i]=true;
for(int i=;i<=m;i++)
if(!f[E[i][]] && !f[E[i][]]) con[E[i][]][E[i][]]=con[E[i][]][E[i][]]=true;
for(int h=;h<=n;h++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(h!=i && h!=j && i!=j && con[i][h] && con[h][j]) con[i][j]=true;
for(int i=;i<=k;i++)
if(con[cut[i][]][cut[i][]]) return;
if(sum<out)
{
out=sum;
for(int i=,j=;i<=n;i++) if(f[i]) ans[j++]=i;
}
} void dfs(int now,int sum)
{
if(sum>=out) return;
if(now==n+)
{
judge(sum);
return;
}
dfs(now+,sum);
f[now]=true; dfs(now+,sum+); f[now]=false;
} void solve1()
{
read(k);
for(int i=;i<=k;i++) read(cut[i][]),read(cut[i][]);
dfs(,);
printf("%d\n",out);
for(int i=;i<=out;i++) printf("%d ",ans[i]);
} void dfs2(int x,int y)
{
id[x]=++tot;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=y) fa[to[i]][]=x,dfs2(to[i],x);
} int getlca(int u,int v)
{
if(u==v) return u;
if(id[u]<id[v]) swap(u,v);
for(int i=;i>=;i--)
if(id[fa[u][i]]>id[v]) u=fa[u][i];
return fa[u][];
} void solve3()
{
tot=; dfs2(,);
for(int j=;j<=;j++)
for(int i=;i<=n;i++)
fa[i][j]=fa[fa[i][j-]][j-];
read(k); int u,v,lca;
for(int i=;i<k;i++)
{
read(u); read(v);
lca=getlca(u,v);
vis[u]|=<<i;
for(int j=fa[u][];j!=lca;j=fa[j][]) vis[j]|=<<i;
vis[v]|=<<i;
for(int j=fa[v][];j!=lca;j=fa[j][])
vis[j]|=<<i;
vis[lca]|=<<i;
}
tot=(<<k)-;
for(int i=;i<=n;i++)
if(vis[i]==tot) { printf("1\n%d",i); return; }
int s,g;
int t1,t2,t3;
if(k==)
{
bool ok=true;;
for(int i=;i<=n;i++)
{
s=vis[i]; g=;
while(s) g+=(s&),s/=;
if(g!=) { ok=false; break; }
if(vis[i]==) t1=i;
else if(vis[i]==) t2=i;
else t3=i;
}
if(ok)
{
printf("3\n%d %d %d",t1,t2,t3);
return;
}
else
{
int d[];
memset(d,,sizeof(d));
for(int i=;i<=n;i++)
{
d[vis[i]]=i;
if(d[tot^vis[i]])
{
printf("2\n%d %d",i,d[tot^vis[i]]);
return;
}
}
}
}
int r1=,r2=,p1;
for(int i=;i<=n;i++)
if(vis[i]!=r1 || vis[i]!=r2)
{
if(vis[i]!=r1) r1=vis[i],p1=i;
else
{
printf("2\n%d %d",p1,i);
return;
}
}
} void init()
{
read(n); read(m);
int u,v;
for(int i=;i<=m;i++)
{
read(u); read(v);
add(u,v);
in[u]++; in[v]++;
E[i][]=u; E[i][]=v;
}
int sum=,fir;
for(int i=;i<=n;i++) if(in[i]!=) sum++,fir=i;
if(sum==) solve2(fir);
else if(n<=) solve1();
else if(k<=) solve3();
} int main()
{
freopen("ping11.in","r",stdin);
// freopen("ping.out","w",stdout);
init();
}
60分暴力
满分做法:
将链上的做法搬到树上
对所有的询问,按他们的lca排序
然后从下到上处理树上的节点,若以当前节点为lca的测试站点还连通,就把当前节点破坏
dfs序+树链剖分维护即可
#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; #define N 100001 int n,m,p; int cut[N*][],lca[N*]; int siz[N],fa[N][]; int cnt,id[N],bl[N]; int q[N*],lr[N][]; bool f[N<<]; int ans[N]; int front[N],nxt[N<<],to[N<<],tot; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
} void init()
{
read(n); read(m);
int u,v;
for(int i=;i<=m;i++)
{
read(u); read(v);
add(u,v);
}
read(p);
for(int i=;i<=p;i++) read(cut[i][]),read(cut[i][]);
} void dfs1(int x,int y)
{
fa[x][]=y; siz[x]=;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=y) dfs1(to[i],x),siz[x]+=siz[to[i]];
} void dfs2(int x,int top)
{
id[x]=++cnt;
bl[x]=top;
int y=;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa[x][] && siz[to[i]]>siz[y]) y=to[i];
if(!y) return;
dfs2(y,top);
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa[x][] && to[i]!=y) dfs2(to[i],to[i]);
} void prelca()
{
for(int i=;i<=;i++)
for(int j=;j<=n;j++)
fa[j][i]=fa[fa[j][i-]][i-];
} int getlca(int u,int v)
{
if(u==v) return u;
if(id[u]<id[v]) swap(u,v);
for(int i=;i>=;i--)
if(id[fa[u][i]]>id[v]) u=fa[u][i];
return fa[u][];
} bool cmp(int a,int b)
{
return lca[a]<lca[b];
} void modify(int k,int l,int r,int pos)
{
f[k]=true;
if(l==r) return;
int mid=l+r>>;
if(pos<=mid) modify(k<<,l,mid,pos);
else modify(k<<|,mid+,r,pos);
} bool query(int k,int l,int r,int opl,int opr)
{
if(l==opl && r==opr) return f[k];
int mid=l+r>>;
if(opr<=mid) return query(k<<,l,mid,opl,opr);
if(opl>mid) return query(k<<|,mid+,r,opl,opr);
return query(k<<,l,mid,opl,mid)|query(k<<|,mid+,r,mid+,opr);
} bool QUERY(int u,int v)
{
while(bl[u]!=bl[v])
{
if(id[u]<id[v]) swap(u,v);
if(query(,,cnt,id[bl[u]],id[u])) return true;
u=fa[bl[u]][];
}
return query(,,cnt,min(id[v],id[u]),max(id[v],id[u])) ;
} void work(int x)
{
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa[x][]) work(to[i]);
for(int i=lr[x][];i<=lr[x][];i++)
if(!QUERY(cut[q[i]][],cut[q[i]][]))
{
modify(,,cnt,id[x]);
ans[++ans[]]=x;
return;
}
} void solve()
{
for(int i=;i<=p;i++) lca[i]=getlca(cut[i][],cut[i][]),q[i]=i;
sort(q+,q+p+,cmp);
for(int i=;i<=n;i++) lr[i][]=p+,lr[i][]=;
for(int i=;i<=p;i++)
{
lr[lca[q[i]]][]=min(lr[lca[q[i]]][],i);
lr[lca[q[i]]][]=max(lr[lca[q[i]]][],i);
}
work();
printf("%d\n",ans[]);
for(int i=;i<=ans[];i++) printf("%d ",ans[i]);
} int main()
{
freopen("ping.in","r",stdin);
freopen("ping.out","w",stdout);
init();
dfs1(,);
dfs2(,);
prelca();
solve();
}
2017 国庆湖南 Day3的更多相关文章
- 2017 国庆湖南 Day5
期望得分:76+80+30=186 实际得分:72+10+0=82 先看第一问: 本题不是求方案数,所以我们不关心 选的数是什么以及的选的顺序 只关心选了某个数后,对当前gcd的影响 预处理 cnt[ ...
- 2017 国庆湖南 Day6
期望得分:100+100+60=260 实际得分:100+85+0=185 二分最后一条相交线段的位置 #include<cstdio> #include<iostream> ...
- 2017 国庆湖南 Day1
卡特兰数 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ] ...
- 2017 国庆湖南 Day4
期望得分:20+40+100=160 实际得分:20+20+100=140 破题关键: f(i)=i 证明:设[1,i]中与i互质的数分别为a1,a2……aφ(i) 那么 i-a1,i-a2,…… i ...
- 2017 国庆湖南Day2
期望得分:100+30+100=230 实际得分:100+30+70=200 T3 数组开小了 ..... 记录 1的前缀和,0的后缀和 枚举第一个1的出现位置 #include<cstdio& ...
- 学大伟业 2017 国庆 Day1
期望得分:100+100+20=220 实际得分:100+100+20=220 (好久没有期望==实际了 ,~\(≧▽≦)/~) 对于 a........a 如果 第1个a 后面出现的第1个b~z 是 ...
- 2017国庆 清北学堂 北京综合强化班 Day1
期望得分:60+ +0=60+ 实际得分:30+56+0=86 时间规划极端不合理,T2忘了叉积计算,用解析几何算,还有的情况很难处理,浪费太多时间,最后gg 导致T3只剩50分钟,20分钟写完代码, ...
- 长乐国庆集训Day3
T1 动态逆序对 题目 [题目描述] 给出一个长度为n的排列a(1~n这n个数在数列中各出现1次).每次交换两个数,求逆序对数%2的结果. 逆序对:对于两个数a[i],a[j](i<j),若a[ ...
- 2017.10.1 国庆清北 D1T1 zhx的字符串题
题目背景 2017国庆清北D1T1 题目描述 你是能看到第一题的 friends 呢. ——hja 何大爷对字符串十分有研究,于是天天出字符串题虐杀 zhx.何大爷今天为 字符串定义了新的权值计算方法 ...
随机推荐
- 按Right-BICEP要求的对任务二的测试用例
测试方法:Right-BICEP 测试计划 1.Right-结果是否正确? 2.B-是否所有的边界条件都是正确的? 3.P-是否满足性能要求? 4.是否有乘除法? 5.是否有括号? 6.是否有真分数? ...
- Ubuntu16.04安装oracle-java8-installer
本篇博客参考 1. 安装默认JRE/JDK 更新 sudo apt-get update 检查是否安装了Java java -version 如果返回The program java can be f ...
- Spring1()
目的: 降低Java开发的复杂性 使用策略: 基于POJO的轻量级和最小侵入式的编程 通过依赖注入和面向接口实现松耦合 基于切面和惯例进行声明式编程 通过切面和模版减少样式代码 依赖注入:由Sprin ...
- Java & hashCode作用
首先,想要明白hashCode的作用,你必须要先知道Java中的集合. 总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set.你知道它们的区别吗?前者集合内的元素 ...
- haproxy调度算法
调度算法详解 用balance指令指明调度算法, 例如:balance roundrobin 1:roundrobin :动态轮询算法,基于后端服务器的总权重做轮询,后端的服务器数量限制在4095 ...
- SSL 重点SSL会话步骤
SSL.TLS协议 在wiki百科查看下,两者的区别 实现SSL协议的软件 OpenSSL开源软件 SSL会话步骤 1:客户端向服务端索取CA证书,然后验证证书 2:客户端与服务端约定一个通信中使 ...
- QList和QVector使用
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QList和QVector使用 本文地址:http://techieliang.com ...
- 【week10】规格说明书练习-吉林市1日游
假设我们全班同学及教师去吉林省吉林市1日游,请为这次活动给出规格说明书. 版本:1.0 编订:于淼 团队:2016级计算机技术全体同学 日期:2016/11/19 1.引言 1.1 编写目的 1.2 ...
- php中ob缓存机制
1.ob缓存运行方式 2.注意:在程序中如果开启ob_start(),所有的echo输出都会保存到ob缓存中,可以使用ob系列函数进行操作,如果没有,默认情况下,在程序执行结束,会把缓存中的数据发送给 ...
- vue render & array of components & vue for & vue-jsx
vue render & array of components & vue for & vue-jsx https://www.cnblogs.com/xgqfrms/p/1 ...