题意: 给定四个数字 k, n, a, b, 其中 a > b,要求最大数 i 使得 i * a + (n - i) * b < n 成立
strategy : 二分 注意用longlong
#include<bits/stdc++.h>
// #include<bits/extc++.h>
#define oo INT_MAX
#define ll long long
#define db double
#define mp(a, b) make_pair(a, b)
#define met(a, b) memset(a, b, sizeof(a))
#define maxn 100009
#define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define _rev(i, a, b) for(int i = (a); i >= (b); --i)
#define _for(i, a, b) for(int i = (a); i < (b) ;++i)
using namespace std;
ll k, n, a, b;
bool is_valid(ll mid){
ll just_play = mid, left = n - mid;
return just_play * a + left * b < k;
}
int main() {
ios::sync_with_stdio(0);
ll t;
cin >> t;
while (t--)
{
cin >> k >> n >> a >> b;
ll ans = 0;
if(n * b >= k){
ans = -1;
}else if(n * a < k){
ans = n;
} else {
ll l = 1, r = n - 1;
while(l <= r){
ll mid = (l + r) >> 1;
is_valid(mid) ? l = mid + 1 : r = mid - 1;
}
ans = r;
}
cout << ans << endl;
}
//system("pause");
}
后来发现, 有一种更巧妙的算法
C: For convenience, we subtract one from K. Then, the answer is -1 if and only if K / B (using integer division) is less than N. Otherwise, subtract N * B from K and subtract B from A. Then, the answer is the minimum of N and K / A (again using integer division). Essentially, we’re figuring out how many times we can add the difference between A and B (i.e. replacing B’s with A’s) until we have too little charge.
This is clearly an O(1) solution for each query, so our overall complexity is O(Q).
#include<bits/stdc++.h>
// #include<bits/extc++.h>
#define oo INT_MAX
#define ll long long
#define db double
#define mp(a, b) make_pair(a, b)
#define met(a, b) memset(a, b, sizeof(a))
#define maxn 100009
#define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define _rev(i, a, b) for(int i = (a); i >= (b); --i)
#define _for(i, a, b) for(int i = (a); i < (b) ;++i)
using namespace std;
ll k, n, a, b;
int main() {
ios::sync_with_stdio(0);
ll t;
cin >> t;
while (t--)
{
cin >> k >> n >> a >> b;
ll ans = 0;
k--;
if( k / b < n){
ans = -1;
}else {
k -= n * b;
a -= b;
ans = min(n, k / a);
}
cout << ans << endl;
}
//system("pause");
}