昨天的 B 题的确有点意思.....
他的题目很含蓄 .... 给你 A 和 C ,C 每秒减 1 ,A 的话给你三个数 b, x, w, 若 b >= x ,b = b - x,否则 a = a - 1, b = w - (x - b)(每秒只完成一个分支)。后面那个式子展开后就发现不管在 if 的哪个分支里面,b 都是减去 x 的,只是当 b < 0 的时候要加上个 w,所以 k 次操作之后 b 变成了 b - k * x + n * w,n 是让这个式子大于 0 的最小值。
a = a - k, c = c - n
然后二分答案就可以了。
图论的话是这样,因为 b 的范围是小于 1000 的,可以枚举 b 的可能的数值,然后建立一个状态转移的图,找到循环节,然后搞啊搞,这种方法好麻烦,到最后的时候还要判断最后一秒的时候是否有用。因为当操作 c - 1 的时候, a 也减了 1,这样就不减少差值,若之前相等的话还要对答案减一。
二分= =,额。
#include<stdio.h>
#include<cmath>
#include<iostream>
using namespace std;
#define LL long long
LL a,b,w,x,c;
bool OK(LL k)
{
LL n=(k*x-b)/w;
if((k*x-b)%w)
n++;
if(k-n>=c-a)
return true;
return false;
}
int main()
{
cin>>a>>b>>w>>x>>c;
LL ub=1e13,lb=-1;
if(c<=a)
{
puts("0");
return 0;
}
while(ub-lb>1)
{
LL m=(ub+lb)>>1;
if(OK(m))
ub=m;
else
lb=m;
}
cout<<ub<<endl;
}
C 嘛,就是给你 n 个数,让你判断有几个位置可以使得这个数列加一个数之后变成等差数列。
分开考虑。1 和 2 的时候比较特殊,1 可以有无数个, 2 最多可以有三个, 剩下的要么是 2 个,要么是 1 个。
最后,要考虑差是 0 的特殊情况,因为这样的话原来可以放两个数的位置, 因为相同就变成一个数了。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define LL long long
LL num[100009];
struct myD
{
LL pos;
LL cnt;
LL w;
}dd[2];
int main()
{
int n ;
scanf("%d", &n);
for(int i = 0; i < n; i++)
cin >> num[i];
if(n == 1)
{
printf("-1");
return 0;
}
sort(num, num + n);
if(n == 2)
{
LL d = abs(num[1] - num[0]);
if(d == 0)
{
puts("1");
printf("%d\n", num[0]);
return 0;
}
if(d == 1 || d % 2)
{
cout << 2 << endl << num[0] - d << " "<< num[1] + d;
return 0;
}
cout << 3 << endl << num[0] - d << " " << num[0] + (d / 2) << " " << num[1] + d << endl;
return 0;
}
dd[0].w = dd[1].w = -1;
dd[0].cnt = dd[1].cnt = 0;
for(int i = 0; i < n - 1; i++)
{
LL d = num[i + 1] - num[i];
if(d == dd[0].w || dd[0].w == -1)
{
dd[0].cnt++;
dd[0].pos = i;
dd[0].w = d;
}else if(d == dd[1].w || dd[1].w == -1)
{
dd[1].cnt++;
dd[1].pos = i;
dd[1].w = d;
}else
{
cout << 0 << endl;
return 0;
}
}
myD * small, *more;
small = dd[0].w < dd[1].w ? &dd[0] : &dd[1];
more = dd[0].w > dd[1].w ? &dd[0] : &dd[1];
if(small->w == -1)
{
if(more->w == 0)
{
cout << 1 << endl <<num[0];
return 0;
}
puts("2");
cout << num[0] - more->w << " " << num[n - 1] + more->w << endl;
return 0;
}
if(more->cnt != 1 || small->w ==0 ||more->w % 2 || more->w / small->w != 2)
{
puts("0");
return 0;
}
puts("1");
cout << num[more->pos] + small->w << endl;
return 0;
}