[解题报告] NOIP 2014 提高组Day1试题
来源:互联网 发布:哪个国家mac口红最便宜 编辑:程序博客网 时间:2024/06/05 14:50
[解题报告] NOIP 2014 提高组Day1试题
1.生活大爆炸版石头剪刀布(rps.cpp/c/pas)
【问题描述】
石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,则不分胜负。在《生活大爆炸》第二季第8集中出现了一种石头剪刀布的升级版游戏。
升级版游戏在传统的石头剪刀布游戏的基础上,增加了两个新手势:
斯波克:《星际迷航》主角之一。
蜥蜴人:《星际迷航》中的反面角色。
这五种手势的胜负关系如表一所示,表中列出的是甲对乙的游戏结果。
现在,小A 和小B 尝试玩这种升级版的猜拳游戏。已知他们的出拳都是有周期性规律的,但周期长度不一定相等。例如:如果小 A以“石头 - 布- 石头- 剪刀- 蜥蜴人- 斯波克”长度为6 的周期出拳,那么他的出拳序列就是“石头- 布- 石头- 剪刀- 蜥蜴人- 斯波克- 石头- 布- 石头- 剪刀- 蜥蜴人- 斯波克- ……”,而如果小B 以“剪刀- 石头- 布- 斯波克- 蜥蜴人”长度为5的周期出拳,那么他出拳的序列就是“剪刀- 石头- 布- 斯波克- 蜥蜴人- 剪刀- 石头- 布-斯波克- 蜥蜴人- ……”
已知小A 和小B 一共进行N 次猜拳。每一次赢的人得1分,输的得0分;平局两人都得0分。现请你统计
【输入】
输入文件名为rps.in
第一行包含三个整数:
第二行包含
【输出】
输出文件名为rps.out
输出一行, 包含两个整数,以一个空格分隔,分别表示小A 、小B 的得分。
【数据说明】
对于100%的数据,
题目分析:
签到题,简单的模拟,我们用一个二维数组将5种不同的出拳随机组合而成的25种情况保存下来,并且,我们只保存胜利的情况(用1来表示),输或者平局的情况不保存(用0来表示),统计两者的出拳能获得多少次胜利即可
Code:
#include <bits/stdc++.h>using namespace std;int Map[5][5];int n1[210],n2[210];int main() { int n,na,nb,ans1=0,ans2=0,t1=-1,t2=-1; scanf("%d%d%d",&n,&na,&nb); Map[0][2]=1;Map[0][3]=1; Map[1][0]=1;Map[1][3]=1; Map[2][1]=1;Map[2][4]=1; Map[3][2]=1;Map[3][4]=1; Map[4][0]=1;Map[4][1]=1; for(int i=0;i<na;i++) { scanf("%d",&n1[i]); } for(int i=0;i<nb;i++) { scanf("%d",&n2[i]); } for(int i=1;i<=n;i++) { if(++t1==na) t1=0; if(++t2==nb) t2=0; ans1+=Map[n1[t1]][n2[t2]]; ans2+=Map[n2[t2]][n1[t1]]; } printf("%d %d",ans1,ans2);}
2.联合权值(link.cpp/c/pas)
【问题描述】
无向连通图G有
【输入】
输入文件名为link.in
第一行包含1个整数
接下来
最后1行,包含
【输出】
输出文件名为link.out
输出共1行,包含2个整数,之间用一个空格隔开,依次为图G上联合权值的最大值和所有联合权值之和
由于所有联合权值之和可能很大,输出它时要对10007取余。
【数据说明】
对于30%的数据,
题目分析:
首先这是一棵树 ,那么我们肯定优先考虑树上DP,题目要求树上两点的距离必须是2,根据无后效性原则,我们大致可以判断每个点直接从父亲处继承。大致的算法思路就出来了!
我们保存每个节点与它距离为1的所有节点的权值的总和,并且将它父亲节点的权值加两遍(等下告诉你为啥)
那么让我们来看一下,当前节点为4时的情况,
即->
对于爷爷节点,算两遍(因为爷爷不会回来照顾孙子)
对于兄弟节点,算一遍(因为兄弟会回来看你)
这样一遍BFS就过啦!
还有最大值的问题,对于每个节点,我们在计算
Code:
#include <bits/stdc++.h>using namespace std;struct Edge { int next; int to;}edge[400010];int head[200010],f[200010],maxn=-210000000,tot=0,w[200010],sum=0,num[200010],first[200010],second[200010],from[200010];void addedge(int x,int y) { edge[++tot].to=y; edge[tot].next=head[x]; head[x]=tot; return ;}void search(int son,int fa) { if(fa) { sum=(long long)(sum+w[son]*(num[fa]-(w[son]%10007)+10007)%10007)%10007; if(son!=from[fa]) maxn=max(maxn,w[son]*first[fa]); else maxn=max(maxn,w[son]*second[fa]); } f[son]=fa; for(int i=head[son];i;i=edge[i].next) { int to=edge[i].to; if(w[to]>second[son]) { if(w[to]==first[son]) { from[son]=0; }else if(w[to]>first[son]) { second[son]=first[son]; first[son]=w[to]; from[son]=to; }else { second[son]=w[to]; } } num[son]=(long long)(num[son]+w[to])%10007; if(to==fa) { num[son]=(long long)(num[son]+w[to])%10007; } } for(int i=head[son];i;i=edge[i].next) { int to=edge[i].to; if(to==fa) { continue; } search(to,son); } return ;}int main() { int n,x,y; scanf("%d",&n); for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); addedge(x,y); addedge(y,x); } for(int i=1;i<=n;i++) { scanf("%d",&w[i]); } search(1,0); printf("%d %d",maxn,sum);}
3.飞扬的小鸟(bird.cpp/c/pas)
【问题描述】
Flappy Bird 是一款风靡一时的休闲手机游戏,玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙。如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败
为了简化问题,我们对游戏规则进行了简化和改编:
1.游戏界面是一个长为
2.小鸟始终在游戏界面内移动。小鸟从游戏界面最左边任意整数高度位置出发,到达游戏界面最右边时,游戏完成
3. 小鸟每个单位时间沿横坐标方向右移的距离为1,竖直移动的距离由玩家控制。如果点击屏幕,小鸟就会上升一定高度
4. 小鸟高度等于0或者小鸟碰到管道时,游戏失败。小鸟高度为
现在,请你判断是否可以完成游戏。如果可以,输出最少点击屏幕数;否则,输出小鸟最多可以通过多少个管道缝隙
【输入】
输入文件名为 bird.in
第1行有3个整数
【输出】
输出文件名为bird.out
共两行
第一行,包含一个整数,如果可以成功完成游戏,则输出1,否则输出0
第二行,包含一个整数,如果第一行为1,则输出成功完成游戏需要最少点击屏幕数,否则,输出小鸟最多可以通过多少个管道缝隙
【数据说明】
对于30%的数据:
对于50%的数据:
对于70%的数据:
对于100%的数据:
题目分析:
这道题大家一眼就能看出来是一道DP题吧!(笑)
我们将横坐标
这题是一道背包:小鸟在往上飞的时候是完全背包,往下掉的时候是01背包,同时,两者只能选其一
为了不冲突,先做完全背包(可由前一个状态和自己转移),再做01背包(只能由前一个状态转移),最后将不合法的剔除。为什么要强调最后将不合法的剔除呢?因为如果完全背包前面的(低处)撞墙,他可以飞的更高(转移)来规避,如果你直接将其剔除,那么后面就无法根据它来转移!
Code:
#include <bits/stdc++.h>using namespace std;int up[100010],down[100010];int w_up[100010],w_down[100010];int f[2][1010];bool wall[100010];int read() { int ans=0,flag=1; char ch=getchar(); while((ch<'0' || ch>'9') && ch!='-') ch=getchar(); if(ch=='-') flag=-1,ch=getchar(); while(ch>='0' && ch<='9') ans=ans*10+ch-'0',ch=getchar(); return ans*flag;}bool change(int& x,int y) { if(x>y || x==-1) { x=y; return true; } return false;}int main() { int n,m,k; n=read(),m=read(),k=read(); for(int i=0;i<n;i++) { up[i]=read(),down[i]=read(); w_down[i+1]=0; w_up[i+1]=m+1; } for(int i=1;i<=k;i++) { int p=read(); wall[p]=true; w_down[p]=read(),w_up[p]=read(); } memset(f,-1,sizeof(f)); for(int i=1;i<=m;i++) { f[0][i]=0; } int ans=0; bool flag; for(int i=1;i<=n;i++) { flag=1; memset(f[i%2],-1,sizeof(f[i%2])); for(int j=1;j<=m;j++) { if(j-up[i-1]>0) { if(j==m) { for(int l=j-up[i-1]+1;l<=m;l++) { if(f[(i-1)%2][l]!=-1) change(f[i%2][j],f[(i-1)%2][l]+1); if(f[i%2][l]!=-1) change(f[i%2][j],f[i%2][l]+1); } } if(f[(i-1)%2][j-up[i-1]]!=-1) change(f[i%2][j],f[(i-1)%2][j-up[i-1]]+1); if(f[i%2][j-up[i-1]]!=-1) change(f[i%2][j],f[i%2][j-up[i-1]]+1); } } for(int j=1;j<=m;j++) { if(j+down[i-1]<=m && f[(i-1)%2][j+down[i-1]]!=-1) { change(f[i%2][j],f[(i-1)%2][j+down[i-1]]); } } if(wall[i]) { for(int j=1;j<=w_down[i];j++) { f[i%2][j]=-1; } for(int j=w_up[i];j<=m;j++) { f[i%2][j]=-1; } } for(int j=1;j<=m;j++) { if(f[i%2][j]!=-1) flag=0; } if(flag) { printf("0\n%d",ans); return 0; } if(wall[i]) ans++; } int minn=2100000000; for(int i=1;i<=m;i++) { if(f[n%2][i]==-1) continue; minn=min(minn,f[n%2][i]); } printf("1\n%d",minn); return 0;}
总体来说,NOIP 2014 提高组Day1题目还是比较简单的,希望大家温故而知新,在以后的联赛中考出好成绩 ღ( ´・ᴗ・` )
by:Chlience
- [解题报告] NOIP 2014 提高组Day1试题
- [解题报告] NOIP 2014 提高组Day2试题
- Noip 2014 提高组复赛 解题报告
- 【NOIP2014提高组】【Day1】【解题报告】
- 【NOIP2013】【提高组】【Day1】【解题报告】
- NOIP2013提高组Day1 解题报告
- 2014 NOIP复赛提高组 C++ 解题报告
- NOIP 2015 提高组 day2 解题报告
- [REVIEW] NOIP 2015 Day1 解题报告
- NOIP 2013 提高组复赛 day1 试题 Vigenere密码
- 2016.7.18 NOIP2014提高组day1解题报告
- 2016 NOIP提高组复赛解题报告 C++
- 2015 NOIP提高组 复赛解题报告 C++
- NOIP 2014 提高组 Day1 T2 联合权值
- Noip提高组 2014 Day1 T2 联合权值 模拟
- NOIP 提高组复赛 day1 国王游戏
- 2016noip提高组day1 换教室
- 2016.7.12 NOIP2013提高组day1解题报告(未完成版)
- java 反射机制
- JAVA的密码算法库
- opencv3.0 车牌号字符的分割
- 标准C语言第五天
- sklearn--交叉验证
- [解题报告] NOIP 2014 提高组Day1试题
- 本地连接阿里云数据库Redis
- 扯淡闲聊
- 放苹果
- python 闭包
- HTML基础
- 标准C语言第六天
- 10.21/22作业
- TensorFlow保存读取数据