Single Round Match 639 500 AliceGameEasy
Problem Statement
Alice and Kirito just played a game.The game consisted of a finite (possibly empty) sequence of turns.You do not know the exact number of turns.The turns were numbered starting from 1.In each turn, exactly one of our two players won.The winner of turn i scored i points.
You are given two longs x and y.Find out whether it is possible that at the end of the game Alice had exactly x points and Kirito had exactly y points.If it is possible, return the smallest number of turns Alice could have won.If the given final result is not possible, return -1 instead.
Definition
- Class AliceGameEasy
- Method findMinimumValue
- Parameters long long , long long
- Returns long long
- Method signature long long findMinimumValue(long long x, long long y)
Limits
- Time limit (s) 2.000
- Memory limit (MB) 256
Constraints
- x and y will be between 0 and 1,000,000,000,000(10^12), inclusive.
Test cases
-
- x 7
- y 14
Returns 2This final result is possible.One possibility is that Alice won turns 1, 2, and 4 (for 1+2+4 = 7 points) and Kirito won turns 3, 5, and 6 (for 3+5+6 = 14 points).However, there are also some other possibilities in which Alice only won two of the six turns, so the correct answer is 2. -
- x 10
- y 0
Returns 4There must have been four turns and Alice must have won all four of them. -
- x 932599670050
- y 67400241741
Returns 1047062Watch out for integer overflow. -
- x 7
- y 13
Returns -1 -
- x 0
- y 0
Returns 0 -
- x 100000
- y 400500
Returns 106
贪心,从高往低贪心。
首先求出1...N的N是多少。(1+N) * N / 2 = x+y
1...M的自然数一定能表示出1...M的所有数。
(为了方便解释,用符号sigma(a,b) = a+(a+1)+...+(b-1)+b )
首先说符合答案的方案一定是x=sigma(m,N)+c ,c 属于 [0,m) 的自然数。就是说把m到N的数都选掉,再选一个0到m-1的数。
如果sigma(m,N) < x <= sigma(m-1,N),那么:
0 < x - sigma(m,N) <= m-1 一定能在剩下的m-1个数中选一个,使它们的和恰好为x
所以得到结论:
1.sigma(m,N) < x <= sigma(m-1,N)的x一定能够表示出来
2.要用(N-M+1)+1个数来表示
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <typeinfo>
#include <fstream>
using namespace std;
typedef long long LL;
class AliceGameEasy {
public:
long long findMinimumValue(long long x, long long y) {
LL N=(long long)sqrt((double)(x+y)+(double)(x+y));
if(N*(N+1)!=x+y+x+y) return -1;
if(x==0) return 0;
LL sum=0;
for(int i=N;i>0;i--)
{
sum+=i;
if(sum>=x) return N-i+1;
}
return 0;
}
};
// CUT begin
ifstream data("AliceGameEasy.sample");
string next_line() {
string s;
getline(data, s);
return s;
}
template <typename T> void from_stream(T &t) {
stringstream ss(next_line());
ss >> t;
}
void from_stream(string &s) {
s = next_line();
}
template <typename T>
string to_string(T t) {
stringstream s;
s << t;
return s.str();
}
string to_string(string t) {
return "\"" + t + "\"";
}
bool do_test(long long x, long long y, long long __expected) {
time_t startClock = clock();
AliceGameEasy *instance = new AliceGameEasy();
long long __result = instance->findMinimumValue(x, y);
double elapsed = (double)(clock() - startClock) / CLOCKS_PER_SEC;
delete instance;
if (__result == __expected) {
cout << "PASSED!" << " (" << elapsed << " seconds)" << endl;
return true;
}
else {
cout << "FAILED!" << " (" << elapsed << " seconds)" << endl;
cout << " Expected: " << to_string(__expected) << endl;
cout << " Received: " << to_string(__result) << endl;
return false;
}
}
int run_test(bool mainProcess, const set<int> &case_set, const string command) {
int cases = 0, passed = 0;
while (true) {
if (next_line().find("--") != 0)
break;
long long x;
from_stream(x);
long long y;
from_stream(y);
next_line();
long long __answer;
from_stream(__answer);
cases++;
if (case_set.size() > 0 && case_set.find(cases - 1) == case_set.end())
continue;
cout << " Testcase #" << cases - 1 << " ... ";
if ( do_test(x, y, __answer)) {
passed++;
}
}
if (mainProcess) {
cout << endl << "Passed : " << passed << "/" << cases << " cases" << endl;
int T = time(NULL) - 1417187263;
double PT = T / 60.0, TT = 75.0;
cout << "Time : " << T / 60 << " minutes " << T % 60 << " secs" << endl;
cout << "Score : " << 500 * (0.3 + (0.7 * TT * TT) / (10.0 * PT * PT + TT * TT)) << " points" << endl;
}
return 0;
}
int main(int argc, char *argv[]) {
cout.setf(ios::fixed, ios::floatfield);
cout.precision(2);
set<int> cases;
bool mainProcess = true;
for (int i = 1; i < argc; ++i) {
if ( string(argv[i]) == "-") {
mainProcess = false;
} else {
cases.insert(atoi(argv[i]));
}
}
if (mainProcess) {
cout << "AliceGameEasy (500 Points)" << endl << endl;
}
return run_test(mainProcess, cases, argv[0]);
}
// CUT end