51Nod-1390-游戏得分

来源:互联网 发布:淘宝免费申请试用在哪 编辑:程序博客网 时间:2024/05/23 22:36

ACM模版

描述

描述

题解

根据题意,不难发现这是一个等差数列,一定用到了等差数列的相关性质。

先考虑输出-1的情况,我们则需要考虑x+y的规律,以及所有能出现的x的规律。这个不难发现,x+y一定是完全平方数,而x可以为1到n^2中除去2的任何一个数,那么我们就很容易搞定-1的情况。

接着,通过贪心,我们知道,想要数目最少,必须尽量选择后边的数,那么我们可以判断后边的数至少有几个才能比x大,那么就一定存在对应的情况来表示x

这里,提供两个代码,思路大差不差,第二个略微优化了,猛一下看不懂很正常,因为中间有公式的推导,其实很简单,就是等差数列的相关公式的推导而已。

代码

One:

#include <iostream>#include <cmath>using namespace std;const int INF = 0x3f3f3f3f;int ans;long long x, y;void dfs(long long round, long long tmp, int count){    if (tmp == 0 && count < ans)    {        ans = count;        return ;    }    for (long long i = round; i > 0; i--)    {        if (ans != INF)        {            break;        }        if (2 * i - 1 > tmp)        {            continue;        }        if (i * i < tmp)        {            break;        }        dfs(i - 1, tmp - 2 * i + 1, count + 1);    }    return ;}int main(int argc, const char * argv[]){    int T;    cin >> T;    while (T--)    {        cin >> x >> y;        int round = (int)sqrt(x + y);        if (round != sqrt(x + y) || x == 2 || y == 2)        {            cout << "-1\n";            continue;        }        ans = INF;        dfs(round, x, 0);        cout << ans << '\n';    }    return 0;}#include <iostream>#include <cmath>#define LL long longusing namespace std;int main(){    LL a, b, sum;    LL T;    cin >> T;    while (T--)    {        cin >> a >> b;        sum = a + b;        double tmp = sqrt(sum * 1.0);        LL count;        if (tmp != floor(tmp) || a == 2 || b == 2)        {            cout << -1 << endl;            continue;        }        else        {            count = tmp;    //  回合总数        }        if (!b)             //  当b为0时可以直接输出回合总数        {            cout << count << endl;            continue;        }        LL t = 0;        bool flag = false;        LL num = 0;        for (LL i = 1; i <= count; ++i)        {            if (i * i > a)            {                break;            }            t = a + i;            num = (2 * count - i + 1) * i / 2;            if (t % 2 == 0 && ((LL)(t / 2.0 + 0.5) <= num))            {                cout << i << endl;                flag = true;                break;            }        }        if (!flag)        {            cout << 0 << endl;        }    }    return 0;}

Two:

#include <iostream>#include <cmath>using namespace std;int T;long long x, y;int main(){    cin >> T;    while (T--)    {        cin >> x >> y;        long long up = (long long)sqrt(x + y);        bool flag = false;        if ((x + y) == up * up)        {            if (x == 0)            {                cout << 0 << endl;                continue;            }            long long i = 1;            if ((x & 1) == 0)            {                i += 1;            }            for (; i <= up; i += 2)            {                if (i * i <= x && x <= 2 * i * up - i * i)                {                    flag = true;                    cout << i << endl;                    break;                }            }        }        if (!flag)        {            cout << -1 << endl;        }    }    return 0;}
0 0
原创粉丝点击