CF Gym Dice Game BFS 暴搜

Time limit  1000 ms

Memory limit  262144 kB

A dice is a small cube, with each side having a different number of spots on it, ranging from 1 to 6.

Each side in the dice has 4 adjacent sides that can be reached by rotating the dice (i.e. the current side) 90 degrees. The following picture can help you to conclude the adjacent sides for each side in the dice.

In this problem, you are given a dice with the side containing 1 spot facing upwards, and a sum n, your task is to find the minimum number of required moves to reach the given sum.

On each move, you can rotate the dice 90 degrees to get one of the adjacent sides to the side that currently facing upwards, and add the value of the new side to your current sum. According to the previous picture, if the side that currently facing upwards contains 1 spot, then in one move you can move to one of sides that contain 2, 3, 4, or 5 spots.

Initially, your current sum is 0. Even though at the beginning the side that containing 1 spot is facing upwards, but its value will not be added to your sum from the beginning, which means that you must make at least one move to start adding values to your current sum.

Input

The first line contains an integer T (1 ≤ T ≤ 200), where T is the number of test cases.

Then T lines follow, each line contains an integer n (1 ≤ n ≤ 104), where n is the required sum you need to reach.

Output

For each test case, print a single line containing the minimum number of required moves to reach the given sum. If there is no answer, print -1.

Example

Input

2
5
10

Output

1
2

本題大意:
  給一個骰子,初始狀態永遠是1點朝上,然後每次可以進行90度翻轉,到另一個面朝上,每翻轉一次得到一個點數就加到sum裡面,問要得到給定的sum需要最少步數

解題思路:
  看到最少步數、較難找出推導過程、數據適中,這就是比較明顯的暴搜標誌。只要把初始狀態對進去,BFS搜到目標就是最少步數。
  注意點也很容易,把可能轉到狀態都放到隊列里去,最後一點就是如果某個狀態之前就被搜過,那就不需要去走了,因為BFS的性質就是每步搜一邊,之前搜到就說明之前的步數更少了

直接看代碼:

#include<bits/stdc++.h>
#define N 10009
using  namespace std;
typedef unsigned long long ll;


int sum;
int a[N];
struct di
{
    int  v,s,n;//v為當前的sum,s是步數,n是當前的朝上的點數
};
int bfs()
{
    queue<di> q;
    di temp;
    temp.v=0;
    temp.s=0;
    temp.n=1;//初始狀態入隊列
    q.push(temp);
    while(!q.empty())//BFS
    {
        di t=q.front();
        q.pop();
        if(t.v<N)
        {
            for(int i=1;i<=6;i++)
            {//     自己    背面      sum值之前被更新了
                if(i==t.n||i+t.n==7||a[t.v+i]!=-1)
                    continue;
                di next;
                next.v=t.v+i;
                next.s=t.s+1;
                next.n=i;
                a[next.v]=next.s;
                q.push(next);
            }
        }
    }
}

int main()
{
    memset(a,-1,sizeof(a));
    bfs();                  //預處理
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&sum);
        printf("%d\n",a[sum]);
    }
}

 

 

转载于:https://www.cnblogs.com/Lin88/p/9528782.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值