51nod 1390 游戏得分

A与B两人玩一个游戏,这个游戏有若干个回合(可能0回合)。游戏的回合依次标号为1,2,3,4...。你不需要关心游戏的内容,现在只要知道第i回合胜者会获得2*i-1分,每回合游戏不存在平局。现在已知A和B在游戏结束时各获得了x分与y分的总分。问A在这个游戏中至少获胜了几盘?如果给出的x与y一定不会出现那么输出-1.
Input
多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5
每组测试数据有相同的结构构成:
每组数据一行包含两个整数x,y,表示A与B最后的总得分,其中0<=x,y<=1,000,000,000,000。
Output
每组数据一行输出,即A最少获胜了几盘,非法的x与y对输出-1。
Input示例
3
8 17
17 8
0 0
Output示例
2
3

0

首先我们肯定是要通过x+y来判断总局数

如果x+y不能被开方,则无答案,否则总局数就是开放后的数n;

之后如果x为0,则输出0。

如果x为n,则输出n。

如果x=2或者y=2,则无答案。

以上都是需要特别判断的。

之后对于a来说,我们想要局数尽可能少,那么就是赢的局数的得分尽可能大。越往后越好。

那么我们从n到1开始贪心。

对于当前第i局,如果第i局的得分小于等于n,那么这一局要拿下,a减去这局得分,num++。继续遍历。

如果当前局大于a了,说明a已经很小了,当前局肯定是不能用的,会超出得分的。那么如果a现在是一个奇数,那么只需要从前面的局数中选择一个恰好等于a的得分的局即可,因为这是一个等差数列,肯定会存在对应的奇数。直接num+1,break即可。

如果当前a是一个偶数,那么我们只需要从前面取出两局,一定能加起来恰好等于a。这是差值等于2的等差数列的性质。直接num+2后break即可。

#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<queue> #include<math.h> using namespace std; long long t; long long a,b; int main() {     cin>>t;     while(t--)     {         cin>>a>>b;         long long falg=0;         long long num=0;         long long z1=a+b;         long long n=sqrt(z1);         if(n*n!=a+b)         {             falg=1;         }         if(falg||a==2||b==2)         {             cout<<"-1"<<endl;             continue;         }         if(a==0)         {             cout<<"0"<<endl;             continue;         }         if(b==0)         {             cout<<n<<endl;             continue;         }         for(long long i=n;i>=1;i--)         {             long long d=2*i-1;             if(a>d)             {                 a-=d;                 num++;             }             else             {                 if(a%2==1)                 {                     num++;                 }                 else                 {                     num+=2;                 }                 break;             }         }         cout<<num<<endl;     } }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值