TC Member SRM 478 DIV 1(CarrotJumping-操作观察)

Problem Statement

 Rabbits often feel hungry, so when they go out to eat carrots, they jump as quickly as possible.

Initially, rabbit Hanako stands at position init. From position x, she can jump to either position 4*x+3 or 8*x+7 in a single jump. She can jump at most 100,000 times because she gets tired by jumping.

Carrots are planted at position x if and only if x is divisible by 1,000,000,007 (i.e. carrots are planted at position 0, position 1,000,000,007, position 2,000,000,014, and so on). Return the minimal number of jumps required to reach a carrot. If it's impossible to reach a carrot using at most 100,000 jumps, return -1.

Definition

 
Class:CarrotJumping
Method:theJump
Parameters:int
Returns:int
Method signature:int theJump(int init)
(be sure your method is public)

Limits

 
Time limit (s):2.000
Memory limit (MB):64

Constraints

-init will be between 1 and 1,000,000,006, inclusive.

Examples

0) 
 
125000000
Returns: 1
She can jump from 125000000 to 1000000007.
1) 
 
281250001
Returns: 2
281250001 -> 1125000007 -> 9000000063
2) 
 
18426114
Returns: 58
3) 
 
4530664
Returns: 478
4) 
 
705616876
Returns: 100000
 
5) 
 
852808441
Returns: -1
She can't reach any carrot by making at most 100,000 jumps.

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.     


可以发现本题的2个操作(设为A,B)满足

1.AB=BA

2.3A=2B

故可得到如下转移图



#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define MAXN (100000)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
typedef long long ll;
class CarrotJumping
{
public:
	ll moveA(int a){return add(mul(4,a),3);	}
	ll moveB(int a){return add(mul(8,a),7);	}
	
	int theJump(int init)
	{
		int &x=init;
		if (!x) return 0;
		if (!moveB(x)) return 1;
		For(i,MAXN*3)
		{
			x=moveA(x);
			if ((!x)&&(i/3*2+i%3<=MAXN)) return i/3*2+i%3;
			if ((!moveB(x))&&(i/3*2+i%3+1<=MAXN)) return i/3*2+i%3+1;
		}
		return -1;
	}
}c;
int main()
{
	freopen("TC-677 SRM 478 DIV1-250CarrotJumping.in","r",stdin);
	
	int a;
	while(cin>>a)
	{
		cout<<c.theJump(a)<<endl;
	}
	
	return 0;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值