TC SRM639-500 Alice Game Easy

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)
(be sure your method is public)

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 2
    This 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 4
    There must have been four turns and Alice must have won all four of them.
    • x 932599670050
    • y 67400241741
    Returns 1047062
    Watch 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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值