题目链接: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;
}