[普及~提高][NOIP2013 提高组] 转圈游戏

题目描述

�n 个小伙伴(编号从 00 到 �−1n−1)围坐一圈玩游戏。按照顺时针方向给 �n 个位置编号,从 00 到 �−1n−1。最初,第 00 号小伙伴在第 00 号位置,第 11 号小伙伴在第 1 号位置,……,依此类推。

游戏规则如下:每一轮第 00 号位置上的小伙伴顺时针走到第 �m 号位置,第 11 号位置小伙伴走到第 �+1m+1 号位置,……,依此类推,第 �−�n−m 号位置上的小伙伴走到第 00 号位置,第 �−�+1n−m+1 号位置上的小伙伴走到第 11 号位置,……,第 �−1n−1 号位置上的小伙伴顺时针走到第 �−1m−1 号位置。

现在,一共进行了 10�10k 轮,请问 �x 号小伙伴最后走到了第几号位置。

输入格式

输入共 11 行,包含 44 个整数 �n、�m、�k、�x,每两个整数之间用一个空格隔开。

输出格式

输出共 11 行,包含 11 个整数,表示 10�10k 轮后 �x 号小伙伴所在的位置编号。

样例

输入数据 1

10 3 4 5

Copy

输出数据 1

5

Copy

数据范围与提示

对于 30% 的数据,0<�<70<k<7;

对于 80% 的数据,0<�<1070<k<107;

对于 100% 的数据,1<�<1061<n<106,0<�<�0<m<n,1≤�≤�1≤x≤n,0<�<1090<k<109。

题解 

这道题我给大家三种解法

解法①:分配率

#include <iostream>
using namespace std;
int cnt(int n, int m, int k, int x)
{
	int ans = 1, a = 10;
	while(k)
    {
		if((k) & (1))
        {
            ans = ans * a % n;
        }	
		a = a * a % n;
		k >>= 1;
	}
	return (x % n + m % n * ans % n) % n;
}
int main()
{
	int n, m, k, x;
	cin >> n >> m >> k >> x;
    cout << cnt(n, m, k, x) << endl;
	return 0;
}

Copy

解法②:递增取余

#include <iostream>
using namespace std;
int main()
{
    long long n, m, k, x,y;
    cin >> n >> m >> k >> x;
    long long x1 = x, x2 = x;
    for (long long i = 0; i < 1e9; i++)
    {
        x += m;
        x %= n;
        if (x == x1)
        {
            x1 = i + 1;
            break;
        }
    }//x1圈后回到x位置
    int j = 1;
    for (int i = 0; i < k / 4; i++)
    {
        j *= 10000;
        j %= x1;
    }
    for (int i = 0; i < k % 4; i++)
    {
        j *= 10;
        j %= x1;
    }
    //剩余j圈
    for (int i = 0; i < j; i++)
    {
        x2 += m;
        x2 %= n;
    }
    cout << x2 << endl;
    return 0;
}

Copy

解法③:快速幂

#include <iostream>
using namespace std;
long long n, m, k, x;
int ksm(long long a, long long b, long long c)
{
	long long d = 1;
	a %= c;
	while (b > 0)
	{
		if (b % 2 == 1)
		    d = (d * a) % c;
		b /= 2;
		a = (a * a) % c;
	}
	return d;
}
int main()
{
	cin >> n >> m >> k >> x;
	k = ksm(10, k, n * m);
	k *= m, x += k;
	cout << x % n;
	return 0;
}
  • 11
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值