算法题每日一练---第90天:三仙归洞

1,971 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第25天,点击查看活动详情

一、问题描述

三个倒扣着的不透明小碗排成一排。

随机挑选一个小碗,将一个小球置于碗中。

然后进行 n 次操作,编号 1∼n。

对于第 i 次操作:

  • 如果 imod2=1imod2=1,则操作内容为将位于中间的碗和位于左边的碗交换位置。
  • 如果 imod2=0imod2=0,则操作内容为将位于中间的碗和位于右边的碗交换位置。

我们不妨用 0,1,2 来表示左、中、右三个位置。

n 次操作全部完成以后,装有小球的碗位于位置 x。

请你计算,所有操作开始前,装有小球的碗所在的初始位置。

题目链接:三仙归洞

二、题目要求

样例

输入:4 2
输出:1

数据范围

前 6 个测试点满足 1≤n≤5
所有测试点满足 1≤n≤2×10^9,0≤x≤2

考察

1.模拟、数学、周期规律
2.建议用时15~20min

三、问题分析

昨天晚上,发现Acwing周赛里面的题目还蛮有意思的,比力扣周赛难度低。今天带来周赛的第二题题解,A了两题就跑了,第三题没看。

做之前先看一下题目的数据范围,n大概是10^9,要求必须在0.5s通过所有测试点。通常来说1s可以进行1e+81e+8次循环,所以这一题暴力法肯定是通过不了的。

我们看看有什么规律:

0  0 1 2
1  1 0 2
2  1 2 0
3  2 1 0
4  2 0 1
5  0 2 1
6  0 1 2

是不是6个为一循环啊!

所以,无论n有多大,只需要%6计算就可以了。

10.png

再回头看一眼题目,题目是告诉我们经历了n次移动,最后小球的位置在x上,求小球一开始的位置。这一题我就正着做,假设小球在0 1 2三个当中的一个,看看哪一个符合最后的x条件就可以了。

四、编码实现

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
    int i,j,n,x;
    int a[6][3]={
                 0,1,2,
                 1,0,2,
                 1,2,0,
                 2,1,0,
                 2,0,1,
                 0,2,1,
    };//规律
    cin>>n>>x;
    for(i=0;i<3;i++)//试错法
    {
        if(a[0][i]==a[n%6][x])//相等
        {
            cout<<i;//输出结果
            return 0;
        }
    }
    return 0;
}

五、测试结果

1.png

2.png