10.4离线赛
来源:互联网 发布:淘宝买书靠谱吗 编辑:程序博客网 时间:2024/06/11 18:19
NOIP2014提高组day1模拟
预分270 实分170
生活大爆炸版石头剪刀布
应得100 实得100
题意:多了两种出法,输赢如下表
每个人的出法都有周期性,问n回合后的得分。
数据:n∈[1,200]
数据太小,一遍循环就可以过了,分数只需要打个表就行,代码很短
联合权值
应得100 实得0
题意:在一棵树上每个点有点权,边的长为一,求所有两点间距离为二的点对的点权乘积的和,和最大的点权乘积。和要对10007取模。
数据:对于60%,n∈[1,2000]
对于100%,n∈[1,200000]
边权∈[1,10000]
这个实得分数其实是想错了的错误得分。
因为两点之间差距为二,那么想当然的变成了第i层与第i-2层的和的乘积,
但是在不同的子树上这样是错的。
然后我在暴力里加了两个东西
1、儿子节点与爷爷节点(父亲的父亲)的乘积
2、与同个子树上一层的乘积(前缀和)
这样就对了
最大的和与上同类
#include<bits/stdc++.h>#define M 200005#define Mod 10007#define ll long longusing namespace std;vector<int>edge[M];ll ans,mx,A[M];void f(int x,int fa1){ ll cnt=0;//前缀和 ll mx1=0,mx2=0; for(int i=0;i<edge[x].size();i++){ int y=edge[x][i]; if(y==fa1)continue; f(y,x); ans+=A[y]*A[fa1];ans%=Mod;//和爷爷 ans+=A[y]*cnt;ans%=Mod;//这一层 cnt+=A[y];//前缀和的算法,这个可以手推一下 mx=max(mx,A[y]*A[fa1]); if(A[y]>mx1)mx2=mx1,mx1=A[y]; else if(A[y]>mx2)mx2=A[y]; mx=max(mx,mx1*mx2);//mx1和mx2是这层的最值 }}int main(){ int n; scanf("%d",&n); for(int i=1;i<n;i++){ int x,y; scanf("%d%d",&x,&y); edge[x].push_back(y); edge[y].push_back(x); } for(int i=1;i<=n;i++)scanf("%lld",&A[i]); f(1,0); printf("%lld %lld\n",mx,ans*2%Mod); return 0;}
飞扬的小鸟
应得70 实得70
题意:模拟一个游戏
1、游戏界面是一个长为 n,高为 m 的二维平面,其中有k 个管道(忽略管道的宽度)。
2、小鸟始终在游戏界面内移动。小鸟从游戏界面最左边 任意整数高度位置出发,到达游戏界面最右边时,游 戏完成。
3、小鸟每个单位时间沿横坐标方向右移的距离为 1,竖直移动的距离由玩家控制。如 果点击屏幕,小鸟就会上升一定高度 X,每个单位时间可以点击多次,效果叠加; 如果不点击屏幕,小鸟就会下降一定高度 Y。小鸟位于横坐标方向不同位置时,上 升的高度 X 和下降的高度 Y 可能互不相同。
4、小鸟高度等于 0 或者小鸟碰到管道时,游戏失败。小鸟高度为 m 时,无法再上升。
若能,则输出1和最小步数,否则输出0和能经过的柱子
数据:对于70%,n∈[5,1000],m∈[5,100]
对于100%,n∈[5,10000],m∈[5,1000]
先是一个dp[ i ][ j ] 在坐标[i,j]上跳了几次
这样每次只往上一层的状态上移下移就行
70是没有优化,每个点一直更新
100就是改成完全背包,因为画一下图就能知道有几个点的计算是重复的,那么可以直接加,这样就该成了O(1)。
但是一开始还是错,错在了两个地方
1、完全背包要把这道题中到不了的地方也要算,不然没有办法算上面的
2、那些没有用的地方最后还有清掉,不然对后面有影响
#include<bits/stdc++.h>#define M 10005using namespace std;struct node1{int up,down;}A[M];struct node2{int l,h,p;node2(){p=0;}}B[M];int dp[2][1005];int main(){ int n,m,k; scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++)scanf("%d%d",&A[i].up,&A[i].down);//读入每个格子的上移下移量 for(int i=1;i<=k;i++){ int x;scanf("%d",&x); scanf("%d%d",&B[x].l,&B[x].h);B[x].p=1;//用计数的方法放柱子 } for(int i=1;i<=n;i++){ memset(dp[i%2],63,sizeof(dp[i%2]));//先清为无限大 int L,R; if(B[i].p)L=B[i].l+1,R=B[i].h-1;//上下界 else L=1,R=m; int p=1; for(int j=1;j<=m;j++){ int d=j+A[i].up; if(d>m)d=m; if(dp[i%2][d]>dp[1-i%2][j]+1)dp[i%2][d]=dp[1-i%2][j]+1;//完全背包开始是只走一步 } for(int j=1;j<=m;j++){ int d=j+A[i].up; if(d>m)d=m; if(dp[i%2][d]>dp[i%2][j]+1)dp[i%2][d]=dp[i%2][j]+1;//最后一步一步累加的走 } for(int j=1;j<=m;j++) if(j-A[i].down>=L&&j-A[i].down<=R&&dp[i%2][j-A[i].down]>dp[1-i%2][j])dp[i%2][j-A[i].down]=dp[1-i%2][j]; for(int j=1;j<=m;j++){ if(dp[i%2][j]<=10000000&&j<=R&&j>=L)p=0;//判断不行的时候也要跳过那些不符合的地方 else dp[i%2][j]=10000005; } if(p){ int cnt=0; for(int j=0;j<i;j++)if(B[j].p)cnt++; printf("0\n%d\n",cnt); return 0; } } int ans=1e9; for(int i=1;i<=m;i++)if(ans>dp[n%2][i])ans=dp[n%2][i]; printf("1\n%d\n",ans); return 0;}
另:这次考试太浪了,第二题暴力都没交,交了的话至少想法错了还能弄个60分
- 10.4离线赛
- 10.26离线赛题解
- 天池离线赛
- 天池离线赛
- 天池离线赛
- 天池离线赛
- 10.3离线赛
- 离线赛20171004总结
- 10.6离线赛
- 离线赛20171006总结
- 20171006离线赛总结
- 20171007离线赛总结
- 离线赛20171007总结
- 10.7离线赛
- 10.8离线赛
- 离线赛20171008总结
- 离线赛20171008总结
- 离线赛总结
- java操作x509数字证书
- ROS03-基础知识-架构及概念
- 计算机是如何启动的?
- js实现上传多张图片
- CF 483D Interesting Array 模拟+线段树
- 10.4离线赛
- 取消WPS自动编号问题
- ROS04-基础知识-工具
- Gym 101142F Folding
- .NET 操作MongoDB入门(一) 安装MongoDB
- SpringMVC源码研究之注解<mvc:annotation-driven />
- Lintcode python之两数组的交
- javaSE之方法反射调用
- MFCC原理及代码