GYM-100952-Mancala【模拟】

23 篇文章 0 订阅
4 篇文章 0 订阅

这里写图片描述
这里写图片描述
这里写图片描述

题目链接:gym-100952-I

题目大意:
玩家1和玩家2玩一个游戏,每个人有n堆石子
游戏规则为:
玩家取自己的n堆石子中的一堆中全部石子,以顺时针顺序,每个石子堆放一个石子,直达全部放完。
注意:如果得到的答案是在第一行中,视为无效。

题目思路:

1.将石子堆化为一维
2.取其中最小的石子数为minnum,答案一定是在石子数为minnum的石子堆中。
3.判断哪一个最小值为答案,即,距离起点最近的那一个石子堆

以下是代码:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <functional>
#include <numeric>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#include <deque>
#include <list>

using namespace std;
long long num[100005];
vector <int> vec;
int main()
{
    int cas = 1;
    int n,r,c;
    while(cin >> n >> r >> c)
    {
        if (n == 0 && r == 0 && c == 0) break;
        vec.clear();
        int pos = 0;
        long long minnum = 1000000005;
        for (int i = 1; i <= n; i++)
        {
            cin >> num[i];
            minnum = min(minnum, num[i]);
        }
        for (int i = 2 * n; i > n; i--)
        {
            cin >> num[i];
            minnum = min(minnum, num[i]);
        }
        for (int i = 1; i <= 2 * n; i++)
        {
            if (num[i] == minnum) vec.push_back(i);
        }
        if (r == 1) pos = c;
        else pos = 2 * n - c + 1;

        long long ans = minnum * 2 * n;

        int len = vec.size();
        int dis = 1000005;
        for (int i = 0; i < len; i++)
        {
            if (vec[i] >= pos)
            {
                dis = min(dis, vec[i] - pos);
            }
            else
            {
                dis = min(dis, 2 * n - pos + vec[i]);
            }
        }
        int end = (dis + pos) % (2 * n);
        if (end == 0) end = 2 * n;

        printf("Case %d:\n",cas++);

        if (end <= n)
        {
            cout << "INVALID\n";
        }
        else
        {
            for (int i = 1; i <= 2 * n; i++)
            {
                num[i] -= minnum;
            }
            for (int i = pos; i < pos + dis; i++)
            {
                int ret = i % (2 * n);
                if (ret == 0) ret = 2 * n;
                num[ret]--;
            }

            int ret = (pos + dis) % (2 * n);
            if (ret == 0) ret = 2 * n;
            num[ret] = ans + dis;

            cout << num[1];
            for (int i = 2; i <= n; i++) cout << " " << num[i];
            cout << endl;
            cout << num[2 * n];
            for (int i = 2 * n - 1; i > n; i--) cout << " " << num[i];
            cout << endl;
        }

    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值