A - A and B CodeForces - 1278B
思路
-
题意: 给我们两个数a,b ,我们可以对这两个数进行任意次操作,每次操作,我选择其中的一个数 ,第一个次操作 使其中一个数 +1, 第二次操作是其中一个数 +2…这样一种操作,问最少需要所少次这样的操作,是这两个数 a、b 变的相等
-
分析:这一题比赛的时候没啥思路,之后看完题解,也只能用规律来概括这一题了那接下来我们就开始找规律吧,我们设 a、b的差值的绝对值为 cha,令cha 依次等于 0,1,2,3,4.。。。。来找规律
0 = 0
1 = 1
2 = 1 + 3 - 2
3 = 1 + 2
4 = 2 + 3 - 1
5 = 1 + 2 + 3 + 4 - 5
6 = 1 + 2 + 3
7 = 1 + 2 + 3 - 4 + 5
......
......
结合⬆️面我们可以找出规律,我们要想拼凑出某个 cha 最多只需要减去一个数
,,那么剩下的就是求前缀和,找出前缀和中第一个大于等于cha 的那个位置pos,然后判断(sum[pos] - cha )%2
是否为0,如果是就是答案(注意为什么是这样来判断ans 的 举个例子 对于 cha == 2 时我们找的 pos = 3, sum[3] = 1 + 2 + 3 --> 这个时候如果我们 把 +2 --> 变成 - ,这个时候原来sum[3] 的值相当于少被减去了两个
2,而这两个
2的值正是 sum[3] - cha 的值 ),否继续对sum[pos + 1] 的位置进行判断,已知道找到符合题意的那个
题解一
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
void fre() { freopen("A.txt","r",stdin), freopen("Ans.txt","w",stdout); }
const int mxn = 1e5 + 5;
#define ll long long
ll sum[mxn];
int main()
{
/* fre(); */
for(int i = 1; i < mxn; i ++)
sum[i] = sum[i - 1] + i;
int t;
scanf("%d", &t);
while(t --)
{
int a, b;
scanf("%d %d", &a, &b);
int cha = abs(a - b);
int pos = lower_bound(sum, sum + mxn, cha) - sum;
for(int i = pos; ; i ++)
{
if((sum[i] - cha) % 2 == 0)
{
printf("%d\n", i);
break;
}
}
}
return 0;
}
题解二
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
void fre() { freopen("A.txt","r",stdin), freopen("Ans.txt","w",stdout); }
const int mxn = 1e5 + 5;
#define ll long long
ll sum[mxn];
int main()
{
/* fre(); */
for(int i = 1; i < mxn; i ++)
sum[i] = sum[i - 1] + i;
int t;
scanf("%d", &t);
while(t --)
{
int a, b;
scanf("%d %d", &a, &b);
int cha = abs(a - b);
int pos = lower_bound(sum, sum + mxn, cha) - sum;
int tmp = sum[pos] - cha;
if(tmp % 2 == 0)
printf("%d\n", pos);
else if(pos % 2 == 0)
printf("%d\n", pos + 1);
else
printf("%d\n", pos + 2);
}
return 0;
}