题意: 一个游戏有n轮,有A和B比赛,谁在第 i 轮得胜,就获得 i 分,给出x,y,问A得x分,B得y分有没有可能,如果有,输出A最少赢的盘数。

解法: 这题是我傻逼了,处理上各种不优越,要使n*(n+1)/2 >= 10^12, n为10^6是不够的,要开大一点,总是细节地方不注意。

做法很简单,先用map或者其他什么东西判断x+y是否为某个n*(n+1)/2, 如果不是,那肯定为-1,再就是x=0有可能要单独考虑,然后就是选一些数凑成x,由于要最少,那么从大的开始凑起,可以暴力地凑,也可以按n,n-1,...1排好,然后搞出前缀和,取个lower_bound,可知,结果就是lower_bound的值,因为左边能满足肯定优先选左边的,直到不满足再从后面选一个且肯定只是1个,所以是对的。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <map>
#define ll long long
using namespace std; map<ll,int> mp;
class AliceGameEasy
{
public:
void init()
{
mp.clear();
ll now = ;
mp[] = ;
for(int i=;i<=;i++)
{
now += i;
mp[now] = i;
}
}
ll sum[];
long long findMinimumValue(long long x, long long y)
{
init();
if(x + y == ) return ;
if(!mp[x+y]) return -;
if(x == 0LL) return ;
int n = mp[x+y];
sum[] = ;
for(int i=;i<=n;i++)
sum[i] = sum[i-] + (n-i+1LL);
int ind = lower_bound(sum+,sum+n+,x)-sum;
return ind;
}
};
05-08 15:11