Codeforces Round #408 (Div. 2) B. C.D.
来源:互联网 发布:ssh权限管理系统源码 编辑:程序博客网 时间:2024/06/05 07:50
B:
题目大意:
给你N个盒子,第一个盒子一开始装着骨头,现在有m个位子上有漏洞,如果带有骨头的盒子移动到了这些位子上,那么骨头就会掉在漏洞上再也不会动。
问最终骨头在哪里、
每一次操作交换两个位子上的盒子。
自己的代码被hack了..其实只要动当前为ans的就可以了
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int vis[1000050];int a[1000050];int main(){ int n,m,k; while(~scanf("%d%d%d",&n,&m,&k)) { memset(vis,0,sizeof(vis)); for(int i=0;i<m;i++) { int x; scanf("%d",&x); vis[x]=1; } int ans=1; while(k--) { int x,y; scanf("%d%d",&x,&y); if(x==ans) { if(vis[x]!=1)ans=y; } else if(y==ans) { if(vis[y]!=1)ans=x; } } printf("%d\n",ans); }}
C:
题目链接:http://codeforces.com/contest/796/problem/C题目的意思是有n个点,n-1条边,现在让你任选一个点当做起点,去掉这个点,然后和这个点连接的所有的点的权值都加一,然后所有和那个点相连的点的点的点权也要加一,有点绕,慢慢理解,1->2->3,就是说去掉1后2和3的点权都要加一,然后问你最大集合中的最小点权。
心得:想法其实差不多,但是我wa了..
我打算dfs随便一个mx来比较与cmx ,mx 的距离.但其实这样是不可以的;
比如下面的话应该从2开始走的,
(所以正确的做法应该是按照题解一样,mx 的相邻的节点都应该是mx或者是cmx.)
自己wa的数据
Input
3
2 2 2
3 2
1 2
Participant’s output
4
Jury’s answer
3
参考http://blog.csdn.net/bless924295/article/details/70244270
#include <cstdio>#include <cstring>#include <iostream>#include <vector>#define inf 0x3f3f3f3fusing namespace std;int a[400000];vector<int >G[400000];int n;int solve(){ int x=0,y=0; int maxval=-inf; for(int i=1;i<=n;i++){ if(a[i]>maxval) maxval=a[i]; } for(int i=1;i<=n;i++){ if(a[i]==maxval) x++; if(a[i]==maxval-1) y++; } int xx=x; int yy=y; bool flag1=true; bool flag2=true; for(int i=1;i<=n;i++){ bool flag3=true; if(a[i]==maxval) x--; else if(a[i]==maxval-1) y--; for(int j=0;j<(int )G[i].size();j++){ if(a[G[i][j]]==maxval){ x--; flag3=false; } if(a[G[i][j]]==maxval-1) y--; } if(x==0){ flag1=false; if(y==0&&flag3) flag2=false; } x=xx,y=yy; } if(!flag1){ if(flag2==0) return maxval; else return maxval+1; } return maxval+2;}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } for(int i=0;i<n-1;i++){ int u,v; scanf("%d%d",&u,&v); G[u].push_back(v); G[v].push_back(u); } int ans=solve(); cout<<ans<<endl; return 0;}
D:
参考http://blog.csdn.net/mengxiang000000/article/details/70146788
题目大意:给你一个树,其中有N个点,N-1条无向边,现在有M个特殊点,问你最多可以切割多少条边,使得每个普通点到最近的特殊点的距离小于等于d.保证有解。
体悟:一开始以为是树dp,结果怎么想都想不出来..
原来就只是个多点bfs而已…
贪心地使得每个点都被遇见一次…因为是树,如果第二次遇到,那么这条边是不用的,
#include<stdio.h>#include<string.h>#include<queue>#include<vector>using namespace std;struct node{ int to,pos;}now,nex;vector<node >mp[300800];int vis[300800];int ans[300800];int main(){ int n,m,k; while(~scanf("%d%d%d",&n,&m,&k)) { queue<int >s; memset(vis,0,sizeof(vis)); memset(ans,0,sizeof(ans)); for(int i=1;i<=n;i++)mp[i].clear(); for(int i=0;i<m;i++) { int x; scanf("%d",&x); s.push(x); vis[x]=1; } for(int i=1;i<=n-1;i++) { int x,y; scanf("%d%d",&x,&y); now.to=y; now.pos=i; mp[x].push_back(now); now.to=x; now.pos=i; mp[y].push_back(now); } while(!s.empty()) { int u=s.front(); s.pop(); for(int i=0;i<mp[u].size();i++) { int v=mp[u][i].to; if(vis[v]==0) { ans[mp[u][i].pos]=1; vis[v]=1; s.push(v); } } } int cnt=0; for(int i=1;i<=n-1;i++)if(ans[i]==0)cnt++; printf("%d\n",cnt); for(int i=1;i<=n-1;i++) { if(ans[i]==0)printf("%d ",i); } printf("\n"); }}
E:待补:http://codeforces.com/contest/796/problem/E dp
..
解题报告: 考虑用f[i][j][x][y]表示考虑完前i个问题,当前总共用了j次机会,对于第一个人还能看x道题,第二个人还能看y道题的最优值,考虑x和y等于0的情况,直接转移就好了。 这里写转出可能会方便一些。 注意到这个复杂度是O(npk2)的,但是当p>2∗nk时,可以全选,那么直接全选就好了,特判一下,所以复杂度是O(n2k)。
心得:这个地方还是挺难想到这个状态的。。
要记录左边,右边还可以看多少次。。看了多少次,看到第几题。。。这样的话满足了dp 的要求。。
别人的代码:
#include<queue> #include<cstdio> #include<string> #include<cstring> using namespace std; int f[2][1005][55][55]; int a[1005],b[1005]; int main() { int n,p,k; scanf("%d%d%d",&n,&p,&k); if(p>2*(n+k-1)/k) p=2*(n+k-1)/k; int n1,n2,x; scanf("%d",&n1); int i,j; for(i=1;i<=n1;i++) { scanf("%d",&x); a[x]=1; } scanf("%d",&n2); for(i=1;i<=n2;i++) { scanf("%d",&x); b[x]=1; } int y; memset(f,-127/3,sizeof(f)); f[0][0][0][0]=0; int p1=1,p2=0; for(i=1;i<=n;i++) { for(j=0;j<=p;j++) { for(x=0;x<k;x++) { for(y=0;y<k;y++) { if(y!=0) f[p1][j+1][k-1][y-1]=max(f[p1][j+1][k-1][y-1],f[p2][j][x][y]+(a[i]||b[i])); else f[p1][j+1][k-1][0]=max(f[p1][j+1][k-1][0],f[p2][j][x][y]+a[i]); if(x!=0) f[p1][j+1][x-1][k-1]=max(f[p1][j+1][x-1][k-1],f[p2][j][x][y]+(a[i]||b[i])); else f[p1][j+1][0][k-1]=max(f[p1][j+1][0][k-1],f[p2][j][x][y]+b[i]); if(x!=0&&y!=0) f[p1][j][x-1][y-1]=max(f[p1][j][x-1][y-1],f[p2][j][x][y]+(a[i]||b[i])); else if(x!=0) f[p1][j][x-1][0]=max(f[p1][j][x-1][0],f[p2][j][x][y]+a[i]); else if(y!=0) f[p1][j][0][y-1]=max(f[p1][j][0][y-1],f[p2][j][x][y]+b[i]); else f[p1][j][0][0]=max(f[p1][j][0][0],f[p2][j][x][y]); } } } p1=1-p1; p2=1-p2; for(j=0;j<=p;j++) for(x=0;x<k;x++) for(y=0;y<k;y++) f[p1][j][x][y]=-100000; } int ans=0; for(j=0;j<=p;j++) for(x=0;x<k;x++) for(y=0;y<k;y++) ans=max(ans,f[p2][j][x][y]); printf("%d\n",ans); return 0; }
阅读全文
0 0
- Codeforces Round #408 Div.2 A B C D
- Codeforces Round #408 (Div. 2) B. C.D.
- Codeforces Round #179 (Div. 2)A、B、C、D
- Codeforces Round #186 (Div. 2)A、B、C、D、E
- Codeforces Round #202 (Div. 2) (A、B、C、D)
- Codeforces Round #211 (Div. 2)(A,B,C,D)
- Codeforces Round #220 (Div. 2)(A,B,C,D)
- Codeforces Round #231 (Div. 2)A, B, C, D
- Codeforces Round #258 (Div. 2)-(A,B,C,D,E)
- Codeforces Round #246 (Div. 2) A,B,C,D
- Codeforces Round #261 (Div. 2) A,B,C,D,E
- Codeforces Round #259 (Div. 2) A/B/C/D
- Codeforces Round #257 (Div. 2) A/B/C/D
- Codeforces Round #256 (Div. 2) A/B/C/D
- Codeforces Round #262 (Div. 2)-A,B,C,D
- Codeforces Round #263 (Div. 2) A,B,C,D,E
- Codeforces Round #264 (Div. 2) A,B,C,D,E
- Codeforces Round #276 (Div. 2) A B C D
- JS简单的更改样式
- 实现计算器4则运算算法-分离算法 理论
- SQL语句使用08-------函数
- 按钮组件
- 移动架构01_UML用例图
- Codeforces Round #408 (Div. 2) B. C.D.
- 《计算机视觉-一种现代方法(第2版)》读书笔记四:中层视觉
- Merge k Sorted Lists(leetcode)
- rotate_array
- “双鸭山大学的来源”
- 四大组件的运行状态
- 【JavaScript】面向对象与原型
- 数据结构基础(3)一些概念
- 一些REST架构设计模式的理解