CF1716 A. 2-3 Moves

2 篇文章 0 订阅
1 篇文章 0 订阅

You are standing at the point 00 on a coordinate line. Your goal is to reach the point nn. In one minute, you can move by 22 or by 33 to the left or to the right (i. e., if your current coordinate is xx, it can become x−3x−3, x−2x−2, x+2x+2 or x+3x+3). Note that the new coordinate can become negative.

Your task is to find the minimum number of minutes required to get from the point 00 to the point nn.

You have to answer tt independent test cases.

Input

The first line of the input contains one integer tt (1≤t≤1041≤t≤104) — the number of test cases. Then tt lines describing the test cases follow.

The ii-th of these lines contains one integer nn (1≤n≤1091≤n≤109) — the goal of the ii-th test case.

Output

For each test case, print one integer — the minimum number of minutes required to get from the point 00 to the point nn for the corresponding test case.

Example

input

Copy

 

4

1

3

4

12

output

Copy

2
1
2
4

翻译一下:给你一个数,判断一个数通过-2 +2 -3 +3这四种运算,至少要多少次才能到0

比较简单的dp,定义一个dp数组,数组的第n个表示,第n个数至少要通过多少次

这个地方我们完全可以不用看+2 +3这两种,因为完全可以用-2 -3的数来代替

如果算出来的是负数,莫非就是-3 -2 -1,其实结果和他们的绝对值也是相同的,写一个函数来获取数组就行

f(x)-> return dp[abs(x)]

然后从第4位开始递推,比较x-2和x-3谁更小,然后再+1,就可以得到结果

但是这里的数据量比较大,所以可以找找规律,刚好发现从第四位开始,每三位的结果都是相同的

2 2 2 3 3 3 4 4 4 5 5 5 ...

然后前面的0 1 2 3的结果我们如果忽略的话(因为可以直接通过数组返回),那相当于从第四位开始就是每三位递增的,如果觉得规律有点难写的话,你就想,1 2 3所对应的结果都是1,代码不久好写了?

直接上代码

#include <iostream>
using namespace std;

int arr[4]={0,2,1,1};

int f(int x){
    if (x<4)return arr[abs(x)];//如果小于4,直接返回
    else{
        if ((float)x/3==x/3)return x/3;//做一个处理,如果刚刚整除,直接返回,如果有余数就+1
        else return x/3+1;
        //这里可以直接写成 return x/3+(x%3?1:0);
    }
}

int main(){
    int T;
    cin>>T;

    while(T--){
        int n;
        cin>>n;
        cout<<f(n)<<endl;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值