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

第一行包含一个正整数T(1≤T≤5000),表示测试数据的组数。

每组数据第一行包含两个正整数n,k(1≤n≤100000,1≤k≤1018),表示序列长度以及你初始的游戏币数量。

第二行包含n个整数a[0],a[1],…,a[n−1](−109≤a[i]≤109)。

输入数据保证所有数据中n的总和不超过1000000。

Output

对于每组数据输出一行一个整数,即你破产的时候你一共按过按钮的次数。如果你运气很好,永远都不会破产,请输出−1。

Sample Input

  1. 1
  2. 5 20
  3. -1 -2 3 4 -5

Sample Output

  1. 5
  2.  
  3. 显然最普通的模拟方法肯定会超时
  4.  
  5. 用另一种模拟方法 时间复杂度n
    模拟第一轮 直到遇到循环 也就是第二次走到某个地方
  6.  
  7. 然后就可以求出 一遍循环走的步数c 和一遍循环减小的数值d
    显然 如果d<=0那么就是死循环 输出-1即可
  8.  
  9. 一开始:
    当前k n*d k为负数
    但是错误性很明显:不可能每次都是循环结束才-k 很可能在循环的中间就已经减到负数了 所以cnt会偏大
  10.  
  11. 调整:
    预留一次循环:就是把k变为k%d(之前的想法是把k变成负数) 预留最后一次循环自己模拟 正确性也很明显
  12.  
  13. 但是还有个bug
    可能每次循环的差值d很小 但是在循环过程中 起伏非常大 在倒数第二遍或者。。。就已经被减为负数了
  14.  
  15. 所以再调整:
    求出d的最大连续和(我这里求的是极限数值) kd大的时候开始最原始模拟
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. //input
  4. #define rep(i,a,b) for(int i=(a);i<=(b);i++)
  5. #define repp(i,a,b) for(int i=(a);i>=(b);i--)
  6. #define RI(n) scanf("%d",&(n))
  7. #define RII(n,m) scanf("%d%d",&n,&m);
  8. #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
  9. #define RS(s) scanf("%s",s);
  10. #define ll long long
  11. #define inf 0x3f3f3f3f
  12. #define REP(i,N) for(int i=0;i<(N);i++)
  13. #define CLR(A,v) memset(A,v,sizeof A)
  14. //////////////////////////////////
  15. #define N 100000+10
  16. ll a[N];
  17. ll vis[N][];
  18. int main()
  19. {
  20. int cas;RI(cas);
  21. while(cas--)
  22. {
  23. int n;
  24. ll k;
  25. RI(n);cin>>k;
  26. rep(i,,n-)
  27. scanf("%lld",&a[i]),vis[i][]=,vis[i][]=;
  28. ll cnt=;
  29. ll maxx=inf;
  30. ll temp=;
  31. while()
  32. {
  33. ll pos=k%n;
  34. if(a[pos]<)//找出中间过程中的最小值之和 这样找并不是精确值 但比最小值要更小 (不精确导致时间花费的更多一点)
  35. temp+=a[pos];
  36. maxx=min( maxx,min(temp,a[pos]) );
  37. k+=a[pos];
  38. cnt++;
  39. if(k<){printf("%lld\n",cnt);break;}
  40.  
  41. if(!vis[pos][])
  42. {
  43. vis[pos][]=cnt;
  44. vis[pos][]=k;
  45. }
  46. else
  47. {
  48. ll d=vis[pos][]-k;
  49. ll c=cnt-vis[pos][];
  50. if(d<=){printf("-1\n");break;}
  51.  
  52. maxx=-maxx;
  53. ll h=k/d;
  54. cnt+=h*c;
  55. k%=d;
  56. while(k<=maxx)//回补
  57. {
  58. k+=d;
  59. cnt-=c;
  60. }
  61. while()
  62. {
  63. ll x=k%n;
  64. k+=a[x];
  65. cnt++;
  66. if(k<){printf("%lld\n",cnt);break;}
  67. }
  68. break;
  69. }
  70. }
  71. }
  72. }
  1.  

老虎ji 剪枝模拟的更多相关文章

  1. USACO 1.3... 虫洞 解题报告(搜索+强大剪枝+模拟)

    这题可真是又让我找到了八数码的感觉...哈哈. 首先,第一次见题,没有思路,第二次看题,感觉是搜索,就这样写下来了. 这题我几乎是一个点一个点改对的(至于为什么是这样,后面给你看一个神奇的东西),让我 ...

  2. 【P1274】魔术数字游戏(搜索+剪枝+模拟)

    做完了这个题的我一口老血喷在屏幕上... 这个题难度不高(~~胡扯~~),就是爆搜就可以了,然而..判断条件灰常多,剪枝也就非常多..然而,这些判断条件又不得不必须满足,所以也就十分容易错... 说一 ...

  3. USACO Chapter 1 解题总结

    USACO Chapter 1 解题总结 1.1.1 Your Ride Is Here 基本字符串操作,无压力. 1.1.2 Greedy Gift Givers 基础模拟题,弄明白题意,不怕麻烦, ...

  4. R语言-laohuji

    项目三-tiger机 说明:每玩一次老ji游戏需要花费一元钱.钻石符号(DD)可以百搭,并且能够将最终的金额加倍. 任务分解: 任务分解的步骤: 将复杂的任务分解为一些简单的子任务: 使用实例: 用通 ...

  5. [C#] 汉字转拼音,支持多音字

    这份代码大概不是严格意义上正确的,但是一般场景用用应该没问题. using System; using System.Collections.Generic; using System.Linq; u ...

  6. [CSP-S模拟测试]:D(暴力+剪枝)

    题目传送门(内部题47) 输入格式 第一行一个正整数$n$.第二行$n$个正整数,表示序列$A_i$. 输出格式 一行一个正整数,表示答案. 样例 样例输入: 530 60 20 20 20 样例输出 ...

  7. [CSP-S模拟测试]:Reverse(模拟+暴力+剪枝)

    题目描述 小$G$有一个长度为$n$的$01$串$T$,其中只有$T_S=1$,其余位置都是$0$.现在小$G$可以进行若干次以下操作: $\bullet$选择一个长度为K的连续子串($K$是给定的常 ...

  8. Noip2011 Mayan游戏 搜索 + 模拟 + 剪枝

    写了一下午,终于AC了. 由于n<=5, 所以不需要太多的剪枝和技巧也能过.可以将操作后的消方块和下落和剪枝函数写到一个结构体中,这样会减少调试难度,更加简洁. 可以采用如下剪枝: 1. 如果当 ...

  9. NOIP 模拟 玩积木 - 迭代加深搜索 / bfs+hash+玄学剪枝

    题目大意: 有一堆积木,0号节点每次可以和其上方,下方,左上,右下的其中一个交换,问至少需要多少次达到目标状态,若步数超过20,输出too difficult 目标状态: 0 1 1 2 2 2 3 ...

随机推荐

  1. [C]va_list可变长参数的使用

    一.概述 运用标准C的头文件stdarg.h提供的宏可以实现函数的自定义传参个数: 二.语法 1.va_list是一个可变长参数类型,在使用可变长参数的函数中可以定义1个或多个va_list类型参数, ...

  2. 37)django-单例模式

    一:单例模式 单例模式,是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类. 通过单例模式可以保证系统中一个类只有一个实例.即一个类只有一个对象实例. 常用例子:数据库连接串,只保 ...

  3. 5)协程二(yeild from)

     一:yield from说明 python从3.3版本开始使用yield from 替代yield  yield from 结构会在内部自动捕获 StopIteration 异常. 这种处理方式与 ...

  4. npm dev run 报错

    解决办法: npm run dev --port 8088 Error: listen EACCES 0.0.0.0:8080at Object.exports._errnoException (ut ...

  5. python-面向对象之继承

    一.继承介绍 继承是一种新建类的方式,新建的类称之为子类或者派生类,被继承的类称为父类/基类/超类 python中继承的特点: 1.子类可以遗传/重用父类的属性 2.子类可以有多个父类 3.Pytho ...

  6. 如何获取STM32 MCU的唯一ID

    前段时间由于应用需要对产品授权进行限制,所以研究了一下有关STM32 MCU的唯一ID的资料,并最终利用它实现了我们的目标. 1.基本描述 在STM32的全系列MCU中均有一个96位的唯一设备标识符. ...

  7. The servlet name already exists.解决方法

    The servlet name already exists.解决方法 当我们建立过同名的servlet文件,然后又将其删掉后再用同类名字建一个servlet时就会报错.解决办法:web.xml里面 ...

  8. jdbcTemplate 调用存储过程。 入参 array 返回 cursor

    注:本文来源<   jdbcTemplate 调用存储过程. 入参 array 返回 cursor   > 需求: java传入一个list object.从数据库找到相关的数据并返回. ...

  9. Pod 找不到头文件 解决方法

    在 BuildSetting 中 搜索 User Header Search Paths 然后在下面 User Header Search Paths 中添加 ${SRCROOT}  再将后面参数改为 ...

  10. (批量更新)对多个符合条件的id做更新操作

    需求描述:把checkbox勾选的对应id的记录的标志位置1或0,这个其实不难的,不过我自己做的话,肯定是多次访问数据库做更新,看了老大的代码,发现差距不是一般的大,老大把sql灵活运用,结果一次访问 ...