LFYZ-OJ ID: 1024 火车站
火车过站
问题描述
火车从始发站(称为第1站)开出,在始发站上车的人数为a,然后到达第2站,在第2站有人上、下车,但上、下车的人数相同,因此在第2站开出时(即在到达第3站之前)车上的人数保持为a人。从第3站起(包括第3站)上、下车的人数有一定规律:上车的人数都是前两站上车人数之和,而下车人数等于上一站上车人数,一直到终点站的前一站(第n-1站),都满足此规律。现给出的条件是:共有N个车站,始发站上车的人数为a,最后一站下车的人数是m(全部下车)。试问p站开出时车上的人数是多少?
输入
输入包含一行, 有四个正整数:a(a<=100),n(n<=20),m(m<=10000)和p(p<=19)
输出
输出为一个整数,为p站开出时车上的人数。
输入样例
1 6 7 3
输出样例
2
分析
思路1
最容易想到的方法就是枚举。枚举第二站上、下车的人数,然后根据题目给出的递推关系判断是否正确。这里的递推关系很清晰,要注意数据规模。
思路2
递推。我们把每站上、下车的人数和上、下车后的总人数用一张表列出来:
车站: 1 2 3 4 5 ……
总数: a a 2a 2a+x 3a+2x ……
上: a x a+x a+2x 2a+3x ……
下: 0 x x a+x a+2x ……
一种简单的方法是根据这个规律使用计算机进行模拟公式计算,我们可以定义一个结构体类型来表示公式,也可以使用数组,这里使用结构体是为了表达更清晰:
struct gs{
int a; //a的个数
int x; //x的个数 公式=ka+jx
}
struct {
gs up; //上的人数
gs down; //下的人数
gs rs; //上、下车后的总人数
}Chezhan[21];
看懂了吗,现在你可以使用循环模拟上面的上、下车过程。
Chezhan[i].up=Chezhan[i-1].up+Chezhan[i-2].up;
Chezhan[i].down=Chezhan[i-1].up; //这样用要使用运算符重载
最后你得到的一个公式是:ka+jx=m,k和j的值在过程中可以计算出来,m和a是已知的。求解x的过程中如果可以除尽,说明有有效值。如果(m-ka)%j!==0,说明除不尽,答案为No Answer.。有了x的值,代入p号站的rs公式中即可得到结果。代码例程1说明了计算过程。
思路3
这里提供另外一种方法,是对斐波那契数列相关属性的运用。通过公式的推导,可以最大可能的提高运算效率。这里涉及到的数列属性最好能够记下来。查看yuyanggo的专栏:NOIP1998火车站。代码见例程2。
代码例程1
#include<iostream>
using namespace std;
struct gs{ //定义公式结构体
int a;
int x;
};
struct{ //定义车站数组
gs rs;
gs up;
gs down;
}INFO[21];
int main(){
int a, n, m, p, x;
scanf("%d%d%d%d", &a, &n, &m, &p);
INFO[1].up.a=1; //初始信息
INFO[2].up.x=1;
INFO[2].down.x=1;
INFO[1].rs.a=1;
INFO[2].rs.a=1;
for(int i=3; i<n; i++){ //在循环中递推
INFO[i].up.a=INFO[i-1].up.a+INFO[i-2].up.a;
INFO[i].up.x=INFO[i-1].up.x+INFO[i-2].up.x;
INFO[i].down.a=INFO[i-1].up.a;
INFO[i].down.x=INFO[i-1].up.x;
INFO[i].rs=INFO[i-1].rs;
INFO[i].rs.a+=INFO[i].up.a;
INFO[i].rs.a-=INFO[i].down.a;
INFO[i].rs.x+=INFO[i].up.x;
INFO[i].rs.x-=INFO[i].down.x;
//printf("%d*a+%d*x\n", INFO[i].rs.a, INFO[i].rs.x);调试代码,输出过程中数据
}
if((m-INFO[n-1].rs.a*a)%INFO[n-1].rs.x){//x不能整除,无答案
printf("No answer.");
return 0;
}else{ //x可以被整除
x=(m-INFO[n-1].rs.a*a)/INFO[n-1].rs.x;
printf("%d", INFO[p].rs.a*a+INFO[p].rs.x*x);
}
return 0;
}
代码例程2
#include <iostream>
using namespace std;
int b[20]={0,1,1}; //斐波那契数列
int main(){
int a,n,m,x,i,k=0;
scanf("%d%d%d%d",&a,&n,&m,&x);
if(x==1){
printf("%d",a);
return 0;
}
for(i=3;i<20;i++) b[i]=b[i-1]+b[i-2]; //计算斐波那契数列
if(n>4) k=(m-(b[n-3]+1)*a)/(b[n-2]-1);
printf("%d",(b[x-1]-1)*k+(b[x-2]+1)*a);
return 0;
}
LFYZ-OJ ID: 1024 火车站的更多相关文章
- [ 订单查询 ] 性能 高并发 : 分表 与 用户id%1024 存放表
逻辑剥离, 保留核心部分 下单 { 核心功能 -- 买家查看订单, 卖家查看收到订单, 修改价格 5个表 附属功能 -- 库存量, 发短信, 给卖家发通知, 订单统计, 销售额统计 } 下单时 一个数 ...
- 九度oj 题目1024:畅通工程
题目描述: 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).经过调查评估,得到的统计表中列出了有可能建设公路的若干条道 ...
- BZOJ 1024: [SCOI2009]生日快乐 dfs
1024: [SCOI2009]生日快乐 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
- 【BZOJ】1024: [SCOI2009]生日快乐(dfs)
http://www.lydsy.com/JudgeOnline/problem.php?id=1024 果然现在弱到连搜索都不会了么..... 一直想二分...但是无论如何也推不出怎么划分... Q ...
- bzoj 1024 [ SCOI 2009 ] 生日快乐 —— 递归
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1024 因为每次把一块切成两块,所以可以枚举从哪里切开,然后递归求解: 一开始用了不太对的贪心 ...
- 【BZOJ 1024】 [SCOI2009]生日快乐
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1024 [题意] [题解] 要求恰好分成n个部分;每个部分的面积都一样; 则dfs的时候 ...
- bzoj 1024 [SCOI2009]生日快乐——模拟
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1024 可以枚举这边放多少块.那边放多少块. 注意精度.不要每次用x*y/base算有多少块, ...
- snowflake 雪花算法 分布式实现全局id生成
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID. 这种方案大致来说是一种以划分命名空间(UUID也算,由于比较常见,所以单独分析)来生成ID的一种算法,这种方案 ...
- 最全的linux命令大全,shell运维手册
shell实例手册 0 说明{ 手册制作: 雪松} 1 文件{ ls -rtl # 按时间倒叙列出所有目录和文件 ll -rt touch file ...
随机推荐
- 使用docker swarm集群心得
本片关于使用docker swarm 集群心得,也是一些经验吧!过程描述可能简单! 根据一些公司使用经历接收一下问题并针对问题作出应对策略 1.docker swarm集群 主节点数必须是单数,也就是 ...
- for循环和foreach循环遍历集合的效率比较
先上代码 package com.test; import java.util.ArrayList; import java.util.LinkedList; import java.util.Lis ...
- CSS伪元素:before/CSS伪元素:before/:after content 显示Font Awesome字体图标:after content 显示Font Awesome字体图标
HTML <a href="javascript:volid(0);"><i class="icon-table"></i> ...
- CVS简单介绍
版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/Jerome_s/article/details/27990707 CVS - Concurrent Ver ...
- IDEA+Maven+各个分支代码进行合并
各个模块的分支代码进行合并到一起:https://blog.csdn.net/xsj_blog/article/details/79198502
- Eclipse中的快捷键
Ctrl+1:快捷修复(数字 1 不是字母 l) 将鼠标悬停到出错区域,按 Ctrl+1,出现快捷修复的菜单, 按上下方向键选择一种修复方式即可. 也可以将光标移动到出错区域,按 F2 + Enter ...
- ES ik分词器使用技巧
match查询会将查询词分词,然后对分词的结果进行term查询. 然后默认是将每个分词term查询之后的结果求交集,所以只要分词的结果能够命中,某条数据就可以被查询出来,而分词是在新建索引时指定的,只 ...
- Struts2的核心——拦截器
虽然以前已经学了很多的拦截器,但是在这里还是想重头梳理一下所有有关拦截器的知识,尤其是struts2中的拦截器 1:拦截器是什么? java里的拦截器是动态拦截Action调用的对象.它提供了一种机制 ...
- Golang 入门系列(五)GO语言中的面向对象
前面讲了很多Go 语言的基础知识,包括go环境的安装,go语言的语法等,感兴趣的朋友可以先看看之前的文章.https://www.cnblogs.com/zhangweizhong/category/ ...
- Scrapy框架基本用法讲解
目标站点:http://quotes.toscrape.com/ (scrape官方练习站点) 这边为了区别Python3.5 和 Python3.7 我修改了scrapy的可执行文件 创建项目文件: ...