过失集.2016.4.15

1.给你 2n 张牌,编号为1,2,3..n,n+1,..2n。这也是牌的最初顺序。一次洗牌是把序列变为n+1,1,n+2,2,n+3,3,n+4,4..2n,n。可以证明,对于任意自然数n,都可以在经过m 次洗牌后第一次重新得到初始的顺序。编程对于输入的自然数n,求出m 的值。数据范围:n<=1000000;一个简单的模拟题,一开始把前50的答案输出出来发现无法找到规律,于是统计后继对象开始模拟暴力,结果60分,我原本分析出来每张牌回到自己原来的位置都有一个固定的数,还以为是要我统计出所有牌回到最初位置的最小公倍数,结果当然是超时,过失在于自己在得出这个结论后没有再向下深入,明明暴力统计所有的数是会超时的,却没有输出具体的所有牌回到最初位置的数值,如果能够多输出几个,是肯定可以看出1回到原位的数值全都是最大的这一点的。

2.Lucky为了掩护大部队,单枪匹马同敌人周旋,后来被敌人包围在某山头……等等,为什么怎么听怎么像狼牙山五壮士!不过不用着急,这次Lucky携带了足够的弹药,完全可以将涌上来的敌人一个一个干掉。Lucky是个神枪手,只要他的枪膛中有子弹,他就能将在他射程m(用从敌人位置到山头的直线距离算)以内的一个敌人瞬间射杀。但如果在射程内没有敌人,出于节约子弹考虑和面子问题,Lucky会等待敌人靠近然后射击。
  正当Lucky为自己的强大而自我膨胀时,他忽然发现了一个致命的失误:他携带的枪是单发枪,每射出一发子弹都必须花k秒钟的时间装子弹。而凶残的敌人才不会花时间等你换子弹呢。他们始终在以1m/s的速度接近山头。而如果在一个敌人到达山头时Lucky无法将他击毙,那么我们可怜的Lucky就将牺牲在敌人的刺刀下。现在Lucky用心灵感应向你发出求助:要保住自己的性命并且歼灭所有敌人,Lucky最多只能用多少时间给枪装上一发子弹?
  说明:假设一开始Lucky的枪中就有一发子弹,并且一旦确定一个装弹时间,Lucky始终会用这个时间完成子弹的装卸。希望你能帮助Lucky脱离险境。

自己的错误代码:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,dis;
int a[120000]={0},b[120000];
bool Check(int mid)
{   
    for(int i=1;i<=n;i++)b[i]=a[i];
    int bul=1,k=0;
for(int i=1;i<=n;i++)
{   
   b[i]-=k;
if(bul==1)
{
if(b[i]<=dis)bul=0;
else k+=b[i]-dis,bul=0;
}
else
{
b[i]-=mid;
k+=mid;
//if(b[i]>dis)k+=b[i]-dis;
if(b[i]<0)return 0;

}
}
return 1;
}
int main(){
scanf("%d%d",&n,&dis);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
sort(a+1,a+n+1);
int l=0,r=10000000;
while(l<r)
{
int mid=(l+r)/2;
if(Check(mid))l=mid+1;
else r=mid-1;
}
if(Check(l))cout<<l;
else cout<<l-1;
return 0;
}
一看到这道题我是看出来可以二分答案的,但是写好后交上去却是60分,检查了一下发现二分本身写得没有问题,但是Check函数写错了,错误就在于我没有加Check函数里注释掉的那一句——我的Check是一个模拟,记录一个K是目前所有的敌人行进了多少米,如果有子弹,那么如果在射程内则直接发射,不然则k+=距离-射程,即此时所有敌人都行进了这么多路程,如果没有子弹,首先便要装弹,所以k+=装弹时间,距离-装弹时间,即若装弹时已经到了那么就不行,然而我却忽略了一点,要是装完弹之后还没有到射程,那么就应该k+=剩余距离-射程,我没有加这一步,结果60分


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值