火车过站

问题描述

火车从始发站(称为第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 火车站的更多相关文章

  1. [ 订单查询 ] 性能 高并发 : 分表 与 用户id%1024 存放表

    逻辑剥离, 保留核心部分 下单 { 核心功能 -- 买家查看订单, 卖家查看收到订单, 修改价格 5个表 附属功能 -- 库存量, 发短信, 给卖家发通知, 订单统计, 销售额统计 } 下单时 一个数 ...

  2. 九度oj 题目1024:畅通工程

    题目描述:     省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).经过调查评估,得到的统计表中列出了有可能建设公路的若干条道 ...

  3. BZOJ 1024: [SCOI2009]生日快乐 dfs

    1024: [SCOI2009]生日快乐 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...

  4. 【BZOJ】1024: [SCOI2009]生日快乐(dfs)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1024 果然现在弱到连搜索都不会了么..... 一直想二分...但是无论如何也推不出怎么划分... Q ...

  5. bzoj 1024 [ SCOI 2009 ] 生日快乐 —— 递归

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1024 因为每次把一块切成两块,所以可以枚举从哪里切开,然后递归求解: 一开始用了不太对的贪心 ...

  6. 【BZOJ 1024】 [SCOI2009]生日快乐

    [题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1024 [题意] [题解] 要求恰好分成n个部分;每个部分的面积都一样; 则dfs的时候 ...

  7. bzoj 1024 [SCOI2009]生日快乐——模拟

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1024 可以枚举这边放多少块.那边放多少块. 注意精度.不要每次用x*y/base算有多少块, ...

  8. snowflake 雪花算法 分布式实现全局id生成

    snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID. 这种方案大致来说是一种以划分命名空间(UUID也算,由于比较常见,所以单独分析)来生成ID的一种算法,这种方案 ...

  9. 最全的linux命令大全,shell运维手册

    shell实例手册 0 说明{ 手册制作: 雪松} 1 文件{        ls -rtl                 # 按时间倒叙列出所有目录和文件 ll -rt    touch file ...

随机推荐

  1. 两种动态SQL

    参考:http://www.cnblogs.com/wanyuan8/archive/2011/11/09/2243483.htmlhttp://www.cnblogs.com/xbf321/arch ...

  2. SQLServer数据事务日志操作

    日志备份 (log backup) 包括以前日志备份中未备份的所有日志记录的事务日志备份. (完整恢复模式) 使用SSMS数据库管理工具备份事务日志 1.连接数据库,选择数据库->右键点击-&g ...

  3. 【笔记】基于Python的数字图像处理

    [博客导航] [Python相关] 前言 基于Python的数字图像处理,离不开相关处理的第三方库函数.搜索网络资源,列出如下资源链接. Python图像处理库到底用哪家 python计算机视觉编程— ...

  4. LVS+Keepalived实现mysql的负载均衡

    1 初识LVS:Linux Virtual Server 1.1 LVS是什么       LVS是Linux Virtual Server的简称,也就是Linux虚拟服务器, 是一个由章文嵩博士发起 ...

  5. 【Teradata】变更viewpoint web登录地址

    1.使用root用户登录原viewpoint地址 ssh root@192.168.253.133 2.查看使用网卡(示例中为eth0) route Kernel IP routing table D ...

  6. Node、TS、Koa学习笔记

    这样定义可以轻松拿到gender属性 这样定义,函数内显示没有gender 这种方法能得到gender但是函数内部没有gender 这种方式能到gender 但是在函数里施symbel属性,外部不能访 ...

  7. JDK1.8源码(九)——java.util.LinkedHashMap 类

    前面我们介绍了 Map 集合的一种典型实现 HashMap ,关于 HashMap 的特性,我们再来复习一遍: ①.基于JDK1.8的HashMap是由数组+链表+红黑树组成,相对于早期版本的 JDK ...

  8. codeforces#1132 F. Clear the String(神奇的区间dp)

    题意:给出一个字符串S,|S|<=500.每次操作可以删除一段连续的相同字母的子串.问,最少操作多少次可以把这个字符串变成空串. 分析:刚开始的思路是,把连续的串给删除掉,然后再....贪心.完 ...

  9. Django create和save方法

    Django的模型(Model)的本质是类,并不是一个具体的对象(Object).当你设计好模型后,你就可以对Model进行实例化从而创建一个一个具体的对象.Django对于创建对象提供了2种不同的s ...

  10. 部署个人wordpress 笔记

    yum list installed | grep php #检查当前安装的PHP包yum remove php.x86_64 php-cli.x86_64 php-common.x86_64 ... ...