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.何大爷今天为 字符串定义了新的权值计算方法 ...
随机推荐
- 20135208 JAVA第四次实验
课程:Java程序与设计 班级:1352 姓名:贺邦 小组成员: 20135212池彬宁 20135208贺邦 学号:20135208 成绩: 指导教师:娄嘉鹏 ...
- qq浏览器的用户体验
用户界面: qq浏览器的用户界面简介,把一些不必要的东西去点,可以很容易让用户找到自己想看的网页,很方便. 记住用户的选择: qq浏览器和QQ相连,可是用QQ账户登录,并且会记住自己访问的高频网页,以 ...
- Unicode和UTF-8
作者:于洋链接:https://www.zhihu.com/question/23374078/answer/69732605来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...
- 团队Alpha冲刺(一)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内 ...
- HttpWebRequest下载文件,乱码问题解决方案
写在前面 今天之所以会总结HttpWebRequest下载文件,主要是因为在使用该类下载文件的时候,有些地方需要注意一下,在实际的项目中遇到过这种问题,觉得还是有必要总结一下的.在下载文件时,最常见的 ...
- window redis php(必须版本>=5.4) 安装
1.下载redis的win版客户端 下载地址: http://code.google.com/p/servicestack/wiki/RedisWindowsDownload 2.选择32bit,64 ...
- react-router之代码分离
概念 无需用户下载整个应用之后才能访问访问它.即边访问边下载.因此我们设计一个组件<Bundle>当用户导航到它是来动态加载组件. import loadSomething from 'b ...
- python脚本批量生成50000条插入数据的sql语句
f = open("xx.txt",'w') for i in range(1,50001): str_i = str(i) realname = "lxs"+ ...
- HDU4043_FXTZ II
题目描述的意思就不说了,自己考虑的时候就是在所有的排列中,碰到大于前面最大的出现数字的时候就乘以一个二分之一,然后求和. 打表后就会发现,答案分子为1*3*5*……*(2*n-1):分母为2*4*6* ...
- HDU2486_A simple stone game
这个题目是这样的,一堆石子有n个,首先第一个人开始可以去1-(n-1)个,接下来两人轮流取石子,每个人可取的石子数必须是一个不超过上一次被取的石子的K倍的整数. 现在求对于一堆数量为n的石子是否为必胜 ...