老虎ji 剪枝模拟
Problem Description
(摘自1995年的电影Casino)
你正在一家赌场的老虎ji面前,你的手上共有k个游戏币。
当你每次按下老虎ji的按钮时,它会随机地报出一个数字d,如果d=0,那么什么事情都不会发生;如果d>0,那么恭喜你,老虎ji会吐给你d个游戏币;但是如果d<0,很不幸,你将需要支付给老虎ji d个游戏币。
这台老虎ji的工作原理很简单,在老虎ji内部有一个长度为n的序列a[0],a[1],…,a[n−1],每当你按下按钮时,如果你手上共有k个游戏币,那么它报出的数字d就是a[kmodn]。
前几次赌博让你尝到了甜头,贪婪的欲望驱动着你不停地按下老虎ji的按钮。当d<0且你支付不了那么多游戏币时,你宣告破产。请问在你破产的时候你一共按过多少次按钮呢?
Input
每组数据第一行包含两个正整数n,k(1≤n≤100000,1≤k≤1018),表示序列长度以及你初始的游戏币数量。
第二行包含n个整数a[0],a[1],…,a[n−1](−109≤a[i]≤109)。
输入数据保证所有数据中n的总和不超过1000000。
Output
Sample Input
- 1
- 5 20
- -1 -2 3 4 -5
Sample Output
- 5
- 显然最普通的模拟方法肯定会超时
- 用另一种模拟方法 时间复杂度n
模拟第一轮 直到遇到循环 也就是第二次走到某个地方- 然后就可以求出 一遍循环走的步数c 和一遍循环减小的数值d
显然 如果d<=0那么就是死循环 输出-1即可- 一开始:
当前k除 n*d 到k为负数
但是错误性很明显:不可能每次都是循环结束才-k 很可能在循环的中间就已经减到负数了 所以cnt会偏大- 调整:
预留一次循环:就是把k变为k%d(之前的想法是把k变成负数) 预留最后一次循环自己模拟 正确性也很明显- 但是还有个bug
可能每次循环的差值d很小 但是在循环过程中 起伏非常大 在倒数第二遍或者。。。就已经被减为负数了- 所以再调整:
求出d的最大连续和(我这里求的是极限数值) 让k比d大的时候开始最原始模拟
- #include<bits/stdc++.h>
- using namespace std;
- //input
- #define rep(i,a,b) for(int i=(a);i<=(b);i++)
- #define repp(i,a,b) for(int i=(a);i>=(b);i--)
- #define RI(n) scanf("%d",&(n))
- #define RII(n,m) scanf("%d%d",&n,&m);
- #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
- #define RS(s) scanf("%s",s);
- #define ll long long
- #define inf 0x3f3f3f3f
- #define REP(i,N) for(int i=0;i<(N);i++)
- #define CLR(A,v) memset(A,v,sizeof A)
- //////////////////////////////////
- #define N 100000+10
- ll a[N];
- ll vis[N][];
- int main()
- {
- int cas;RI(cas);
- while(cas--)
- {
- int n;
- ll k;
- RI(n);cin>>k;
- rep(i,,n-)
- scanf("%lld",&a[i]),vis[i][]=,vis[i][]=;
- ll cnt=;
- ll maxx=inf;
- ll temp=;
- while()
- {
- ll pos=k%n;
- if(a[pos]<)//找出中间过程中的最小值之和 这样找并不是精确值 但比最小值要更小 (不精确导致时间花费的更多一点)
- temp+=a[pos];
- maxx=min( maxx,min(temp,a[pos]) );
- k+=a[pos];
- cnt++;
- if(k<){printf("%lld\n",cnt);break;}
- if(!vis[pos][])
- {
- vis[pos][]=cnt;
- vis[pos][]=k;
- }
- else
- {
- ll d=vis[pos][]-k;
- ll c=cnt-vis[pos][];
- if(d<=){printf("-1\n");break;}
- maxx=-maxx;
- ll h=k/d;
- cnt+=h*c;
- k%=d;
- while(k<=maxx)//回补
- {
- k+=d;
- cnt-=c;
- }
- while()
- {
- ll x=k%n;
- k+=a[x];
- cnt++;
- if(k<){printf("%lld\n",cnt);break;}
- }
- break;
- }
- }
- }
- }
老虎ji 剪枝模拟的更多相关文章
- USACO 1.3... 虫洞 解题报告(搜索+强大剪枝+模拟)
这题可真是又让我找到了八数码的感觉...哈哈. 首先,第一次见题,没有思路,第二次看题,感觉是搜索,就这样写下来了. 这题我几乎是一个点一个点改对的(至于为什么是这样,后面给你看一个神奇的东西),让我 ...
- 【P1274】魔术数字游戏(搜索+剪枝+模拟)
做完了这个题的我一口老血喷在屏幕上... 这个题难度不高(~~胡扯~~),就是爆搜就可以了,然而..判断条件灰常多,剪枝也就非常多..然而,这些判断条件又不得不必须满足,所以也就十分容易错... 说一 ...
- USACO Chapter 1 解题总结
USACO Chapter 1 解题总结 1.1.1 Your Ride Is Here 基本字符串操作,无压力. 1.1.2 Greedy Gift Givers 基础模拟题,弄明白题意,不怕麻烦, ...
- R语言-laohuji
项目三-tiger机 说明:每玩一次老ji游戏需要花费一元钱.钻石符号(DD)可以百搭,并且能够将最终的金额加倍. 任务分解: 任务分解的步骤: 将复杂的任务分解为一些简单的子任务: 使用实例: 用通 ...
- [C#] 汉字转拼音,支持多音字
这份代码大概不是严格意义上正确的,但是一般场景用用应该没问题. using System; using System.Collections.Generic; using System.Linq; u ...
- [CSP-S模拟测试]:D(暴力+剪枝)
题目传送门(内部题47) 输入格式 第一行一个正整数$n$.第二行$n$个正整数,表示序列$A_i$. 输出格式 一行一个正整数,表示答案. 样例 样例输入: 530 60 20 20 20 样例输出 ...
- [CSP-S模拟测试]:Reverse(模拟+暴力+剪枝)
题目描述 小$G$有一个长度为$n$的$01$串$T$,其中只有$T_S=1$,其余位置都是$0$.现在小$G$可以进行若干次以下操作: $\bullet$选择一个长度为K的连续子串($K$是给定的常 ...
- Noip2011 Mayan游戏 搜索 + 模拟 + 剪枝
写了一下午,终于AC了. 由于n<=5, 所以不需要太多的剪枝和技巧也能过.可以将操作后的消方块和下落和剪枝函数写到一个结构体中,这样会减少调试难度,更加简洁. 可以采用如下剪枝: 1. 如果当 ...
- NOIP 模拟 玩积木 - 迭代加深搜索 / bfs+hash+玄学剪枝
题目大意: 有一堆积木,0号节点每次可以和其上方,下方,左上,右下的其中一个交换,问至少需要多少次达到目标状态,若步数超过20,输出too difficult 目标状态: 0 1 1 2 2 2 3 ...
随机推荐
- [C]va_list可变长参数的使用
一.概述 运用标准C的头文件stdarg.h提供的宏可以实现函数的自定义传参个数: 二.语法 1.va_list是一个可变长参数类型,在使用可变长参数的函数中可以定义1个或多个va_list类型参数, ...
- 37)django-单例模式
一:单例模式 单例模式,是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类. 通过单例模式可以保证系统中一个类只有一个实例.即一个类只有一个对象实例. 常用例子:数据库连接串,只保 ...
- 5)协程二(yeild from)
一:yield from说明 python从3.3版本开始使用yield from 替代yield yield from 结构会在内部自动捕获 StopIteration 异常. 这种处理方式与 ...
- npm dev run 报错
解决办法: npm run dev --port 8088 Error: listen EACCES 0.0.0.0:8080at Object.exports._errnoException (ut ...
- python-面向对象之继承
一.继承介绍 继承是一种新建类的方式,新建的类称之为子类或者派生类,被继承的类称为父类/基类/超类 python中继承的特点: 1.子类可以遗传/重用父类的属性 2.子类可以有多个父类 3.Pytho ...
- 如何获取STM32 MCU的唯一ID
前段时间由于应用需要对产品授权进行限制,所以研究了一下有关STM32 MCU的唯一ID的资料,并最终利用它实现了我们的目标. 1.基本描述 在STM32的全系列MCU中均有一个96位的唯一设备标识符. ...
- The servlet name already exists.解决方法
The servlet name already exists.解决方法 当我们建立过同名的servlet文件,然后又将其删掉后再用同类名字建一个servlet时就会报错.解决办法:web.xml里面 ...
- jdbcTemplate 调用存储过程。 入参 array 返回 cursor
注:本文来源< jdbcTemplate 调用存储过程. 入参 array 返回 cursor > 需求: java传入一个list object.从数据库找到相关的数据并返回. ...
- Pod 找不到头文件 解决方法
在 BuildSetting 中 搜索 User Header Search Paths 然后在下面 User Header Search Paths 中添加 ${SRCROOT} 再将后面参数改为 ...
- (批量更新)对多个符合条件的id做更新操作
需求描述:把checkbox勾选的对应id的记录的标志位置1或0,这个其实不难的,不过我自己做的话,肯定是多次访问数据库做更新,看了老大的代码,发现差距不是一般的大,老大把sql灵活运用,结果一次访问 ...