题目链接:River Hopscotch
代码:
#include
#include
#include
using namespace std;
typedef long long LL;
const int MAX = 50005;
const LL INF = 1000000005;
LL L, N, M, lb, ub, mid;
LL a[MAX];
bool solve(LL x)
{
int st = 0, ed = 1, sum = 0;
for(; ed=x)//寻找满足条件的区间
{
st = ed;//开始下一个区间
sum++;
}
}
if(sum>=N-M-1) return 1;
else return 0;
}
int main()
{
scanf("%lld%lld%lld", &L, &N, &M);
a[0] = 0;
for(int i=1; i<=N; i++)
scanf("%lld", &a[i]);
a[N+1] = L;
N = N+2;//注意加上首尾的石头
sort(a, a+N);
lb = 0, ub = INF;
while(ub-lb>1)
{
mid = (ub+lb)/2;
if(solve(mid)) lb = mid;
else ub = mid;
}
printf("%lld\n", lb);
return 0;
}
题目链接:Monthly Expense
代码:
#include
#include
#include
using namespace std;
const int MAX = 100001;
int a[MAX];
int N, M, lb, ub, mid;
bool solve(int x)
{
int sum = 0, cnt = 1;
for(int i=0; ix) return 1;//证明x太小
if(sum+a[i]<=x)
{
sum += a[i];
}
else
{
cnt++;
sum = 0;
i--;
}
}
if(cnt<=M) return 0;//x足够大
else return 1;
}
int main()
{
lb = 0, ub = 1;
scanf("%d%d", &N, &M);
for(int i=0; ilb+1)
{
mid = (ub+lb)/2;
if(solve(mid)) lb = mid;
else ub = mid;
}
printf("%d\n", ub);
return 0;
}
题目链接:Drying
注意:k可能为1,需要单独讨论
。代码:
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int MAX = 1e5+50;
string s;
LL n, a[MAX], k, lb, ub, mid;
bool solve(LL x)
{
LL cnt = 0, b;
for(LL i=0; ilb+1)
{
mid = (ub+lb)/2;
if(solve(mid)) lb = mid;
else ub = mid;
}
printf("%lld\n", ub);
return 0;
}
题目链接:Cow Acrobats
参考博文:POJ Cow Acrobats
代码:
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int MAX = 50005;
const LL INF = 1e9+5;
struct Node
{
LL w, s;
bool operator < (const Node &A) const
{
return w+s
题目链接:Dropping tests
参考博文:Dropping tests
代码:
#include
#include
#include
using namespace std;
const int MAX = 1005;
struct Node
{
double a, b;
};
Node c[MAX];
double t[MAX];
int k, n;
double lb, ub, mid;
bool solve(double x)
{
for(int i=0; i=0) return 1;//x可以更大
else return 0;
}
int main()
{
while(scanf("%d%d", &n, &k)!=EOF)
{
if(n==0 && k==0) break;
lb = 0, ub = 101;
for(int i=0; i
题目链接:K Best
代码:
#include
#include
#include
using namespace std;
const int MAX = 100005;
const int INF = 1e7+1;
struct Node
{
int v, w;
}a[MAX];
struct Nod
{
double x;//注意数据类型
int id;
bool operator < (const Nod &A) const
{
if(x==A.x)
return idA.x;
}
}t[MAX];
int k, n;
double lb, ub, mid;//注意数据类型
bool solve(double x)
{
for(int i=0; i=0) return 1;
else return 0;
}
int main()
{
scanf("%d%d", &n, &k);
for(int i=0; ilb+1e-6)//注意精度
{
mid = (ub+lb)/2;
if(solve(mid)) lb = mid;
else ub = mid;
}
for(int i=0; i
题目链接:Median
参考博文:POJ 3579 Median 查找中间值 二分
代码:
#include
#include
#include
using namespace std;
typedef long long LL;
const int MAX = 100005;
LL x[MAX], N, M;
LL lb, ub, mid;
bool solve(LL mid)
{
LL cnt = 0;
for(int i=0; i=M) return 0;//mid可以减少
else return 1;//mid可以增加
}
int main()
{
while(scanf("%lld", &N)!=EOF)
{
M = (N-1)*N/2;
if(M%2) M = M/2+1;
else M = M/2;
for(int i=0; ilb+1)
{
mid = (lb+ub)/2;
if(solve(mid)) lb = mid;
else ub = mid;
}
printf("%lld\n", ub);
}
return 0;
}
题目链接:Matrix
参考博文:POJ - 3685 Matrix 二分
代码:
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const LL INF = 1<<29;
int T;
LL lb, ub, mid, N, M;
LL caculate(LL m, LL n)
{
return m*m+100000*m+n*n-100000*n+m*n;
}
bool solve(LL x)
{
LL cnt = 0;
for(int j=1; j<=N; j++)
{
LL l = 1, r = N, mid;
//寻找合适的元素下标
while(r>=l)
{
mid = (r+l)/2;
if(caculate(mid, j)<=x)
l = mid+1;
else
r = mid-1;
}
cnt += l-1;
}
if(cnt>=M) return 0;
else return 1;
}
int main()
{
scanf("%d", &T);
while(T--)
{
scanf("%lld%lld", &N, &M);
//注意初始数据
lb = -(LL)(N*N*3+100000*N), ub = (LL)(N*N*3+100000*N);
while(ub>lb+1)
{
mid = (lb+ub)/2;
if(solve(mid)) lb = mid;
else ub = mid;
}
printf("%lld\n", ub);
}
return 0;
}
题目链接:Telephone Lines
参考博文:POJ 3662 Telephone Lines 题解 《挑战程序设计竞赛》
代码:
#include
#include
#include
#include
#include
using namespace std;
const int MAX = 1005;
const int INF = 1000001;
int N, P, K, A, B, L, lb, ub, mid;
int d[MAX], vis[MAX];
struct edge
{
int v, d;
edge(int v = 0, int d = 0): v(v), d(d){}
bool operator < (const edge &A) const
{
return d>A.d;
}
};
vector G[MAX];
int dijstra(int x)
{
memset(vis, 0, sizeof(vis));//注意,使用vis可以减枝,否则超时
fill(d, d+N+1, INF);
priority_queue q;
d[1] = 0;
q.push(edge(1, d[1]));
while(!q.empty())
{
edge u = q.top(); q.pop();
int uv = u.v, ud = u.d;
vis[uv] = 1;
if(d[uv]=x) dis = d[uv]+1;//一定是>=
else dis = d[uv];
if(!vis[t] && dislb+1)
{
mid = (ub+lb)/2;
int n = dijstra(mid);
if(n>K) lb = mid;//一定保证大于等于mid的至少有k+1个,才能代表mid可以作为结果
else ub = mid;
}
if(lb>INF)
printf("-1\n");
else
printf("%d\n", lb);
return 0;
}
题目链接:Garland
参考博文:POJ—1759(Garland,二分一个,求另一个的最优)
代码:
#include
#include
#include
#include
#include
using namespace std;
const double INF = 1002;
double A, B, H, lb , ub, mid;
int N;
bool solve(double x)
{
double H2 = A, H1 = x;//一定使用变量存储
for(int i=3; i<=N; i++)
{
H = H1*2+2-H2;
if(H<0) return 1;//小于0,表示x不够大
if(H+2>H1) return 0;//减枝,递增且已经大于0,则不会再小于0
H2 = H1;
H1 = H;
}
return 0;
}
int main()
{
while(scanf("%d%lf", &N, &A)!=EOF)
{
lb = -1, ub = INF;
//二分求第2个变量
for(int i=0; i<100; i++)
{
mid = (lb+ub)/2.0;
if(solve(mid)) lb = mid;
else ub = mid;
}
//得到最优的第2个变量,再从头到尾算一遍
for(int i=3; i<=N; i++)
{
H = ub*2+2-A;
A = ub;
ub = H;
}
printf("%.2f\n", H);
}
return 0;
}
题目链接:Showstopper
参考博文:POJ-3484-Showstopper
代码:
#include
#include
#include
using namespace std;
typedef long long LL;
const long long INF = 1LL<<35;
const int MAX = 5000000;
LL X, Y, Z, t, ans;
LL lb, ub , mid;
string s;
struct Node
{
LL x, y, z;
}f[MAX];
LL solve(LL x)
{
LL cnt = 0;
for(int i=0; i=f[i].x)
cnt += min(x-f[i].x, f[i].y-f[i].x)/f[i].z+1;
}
return cnt;
}
void compute()
{
lb = 0, ub = INF, ans = 0;
while(ub>lb+1)
{
mid = (lb+ub)/2;
if(solve(mid)%2==0) lb = mid;
else ub = mid;
}
if(ub==INF)
{
printf("no corruption\n");
}
else
{
printf("%lld %lld\n", ub, solve(ub)-solve(ub-1));
}
}
int main()
{
//本题的难点在于输入。不同测试样例之间有多个空行,输入结束后需要在循环外在加一个处理
t = 0;
while(getline(cin, s))
{
if(s.size()==0)
{
if(t==0)
continue;
compute();
t = 0;
}
else
{
int a[5] = {0}, k = 0;
for(int i=0; i
题目链接:Bound Found
参考博文:POJ-Bound Found | 尺取法+绝对值特性
代码:
#include
#include
#include
#include
#define LL long long
#define P pair
using namespace std;
const int maxn=1e5+10;
const int INF=0x3f3f3f3f;
P p[maxn];
bool cmp(P a,P b)
{
return a.firstansr) swap(ansl,ansr);
printf("%d %d %d\n",ans,ansl+1,ansr);
}
}
return 0;
}