二分法

来源:互联网 发布:linux 增加环境变量 编辑:程序博客网 时间:2024/05/16 04:38

a、b、c、d是在区间(1,200]内的整数,找出所有符合如下关系式的组合。 

a^3 = b^3 + c^3 + d^3(b<=c<=d) 
Output 
将组合按a由小到大的顺序排列。 
若两个式子中的a大小相等,则按b由小到大排列,若b也相等,则按c由小到大排列。 
输出形式如引号内所示“a^3 = b^3 + c^3 + d^3”,其中a、b、c、d为整数。


#include<stdio.h>int main(){    int a,b,c,d,i,j,left,right,mid;    for(a=2;a<=200;a++)        for(b=2;b<a;b++)            for(c=b;b*b*b+c*c*c<a*a*a;c++)                {                    left=c;                    right=a;            while(left<right)                {                    mid=(left+right)/2;                    if(b*b*b+c*c*c+mid*mid*mid> a*a*a)                            right=mid;                    else if(b*b*b+c*c*c+mid*mid*mid< a*a*a)                            left=mid+1;                    else if(b*b*b+c*c*c+mid*mid*mid==a*a*a)                    {                        printf("%d^3 = %d^3 + %d^3 + %d^3\n",a,b,c,mid);                            break;                    }                }            }                 return 0;    }
1039修路
Description

前段时间,某省发生干旱,B山区的居民缺乏生活用水,现在需要从A城市修一条通往B山区的路。假设有A城市通往B山区的路由m条连续的路段组成,现在将这m条路段承包给n个工程队(nm≤ 300)。为了修路的便利,每个工程队只能分配到连续的若干条路段(当然也可能只分配到一条路段或未分配到路段)。假设每个工程队修路的效率一样,即每修长度为1的路段所需的时间为1。现在给出路段的数量m,工程队的数量n,以及m条路段的长度(这m条路段的长度是按照从A城市往B山区的方向依次给出,每条路段的长度均小于1000),需要你计算出修完整条路所需的最短的时间(即耗时最长的工程队所用的时间)。

Input

第一行是测试样例的个数T ,接下来是T个测试样例,每个测试样例占2行,第一行是路段的数量m和工程队的数量n,第二行是m条路段的长度。

Output

对于每个测试样例,输出修完整条路所需的最短的时间。

Sample Input

2

4 3

100 200 300 400

9 4

250 100 150 400 550 200 50 700 300

Sample Output

400

900

#include<stdio.h>int c[301],n,m,T;int check(int u){    int cnt1;    int temp;    for(int i=0;i<m;i++)    {        if(temp+c[i]<=u)   //一个工程队修小于mid长度的路        temp+=c[i];        else        {            temp=c[i];   //把temp重新赋值            cnt1++;            if(cnt1>n)                return -1;    //mid太小了        }    }    return -2;     //mid太大了,或者正好。}int binary(int low,int high){    int mid;    while(low<high)    {        mid=(low+high)/2;        int flag=check(mid);        if(flag==-1)        {            low=mid+1;        }        else            high=mid;    }    return low;}int main(){    scanf("%d",&T);    while(T--)    {        int cnt=0,_max=0;        scanf("%d %d",&m,&n);  //m条路,n工程队        for(int i=0;i<m;i++){            scanf("%d",&c[i]);        cnt+=c[i];        if(c[i]>_max)        {            _max=c[i];        }      }      printf("%d\n",binary(_max,cnt));    }}



就业Time Limit: 1000 MSMemory Limit: 32768 KTotal Submit: 36(15 users)Total Accepted: 13(11 users)Rating: Special Judge: NoDescription

    可怜的小胖子因为虚度了大学,工作没找到,考研没考好~结果就去修水管了,连修水管也要试用期,万事开头难,刚开始小胖子就遇到难题了T^T

    维修老板给了小胖子一些水管,水管有个特性,就是上面只有一个孔,用于进水,下面有2,3,4,…,k个孔,用于出水。总水源是由一个孔流出水来的,也就是说只有一根水管的入口可以与水源连接,其他水管需要级联到这根入水管,老板给了小胖子k-1根水管,即出孔为2,3,…,k的水管各一根。问现在需要n个孔流出水来,至少需要用多少根水管,只要小胖子答对了,就可以拥有这份工作了。

Input本题有多组数据,每组数据输入两个正整数n和k,满足(1 ≤n ≤ 1018,2 ≤k ≤ 109)。Output对于每组数据输出一个答案占一行。如果不存在方案则输出-1,否则输出管子的最少根数。Sample Input

4 3

5 5

8 4

Sample Output

2

1

-1

Hint用%lld不要用%I64dAuthorsunshine@hrbust


 选择x根管子 的话,最优选择是k ,k-1,k-2.....(k-x+1)
首项k-x+1 末项 k   项数 x   
 如果选择了两根或以上的x根管子,
可以出水的口 为 所有管子之和 -x
比如   有2,3,4,5 的管子,选择了4,5 的
最终出水的 是 4+5-1个口 ,所以是 sum-(x-1) 



#include <iostream>#include <stdio.h>using namespace std;long long n, k;int check(long long x){      long long v = (2*k+1-x)*x/2-(x-1);     //1/2(k-x+1 + k)*x 为等差数列求和公式    -(x-1)为连接过程中要减掉的出口数  x个管连接,要减掉x-1个出口      if(v == n) return 1;      if(v > n) return 2;      if(v < n) return 3;}int main(){      long long left, right;      bool flag;      while(scanf("%lld %lld", &n, &k) != EOF) {            flag = true;            if(n == 1) printf("0\n");     //还有n=1            else if(n > ((k+2)*(k-1)/2-(k-2))) printf("-1\n");      //最大的情况为用了k个管  1/2(2+k)  * (k-1)      -( (k-1)-1))            else {                  left = 1; right = k-1;           //2---k                  while(left < right) {                        long long mid = (left + right) / 2;                        if(check(mid)==1) {                              printf("%lld\n", mid);                              flag = false;                              break;                        }                        else if(check(mid)==2) {                              right = mid;                        }                        else if(check(mid)==3) {                              left = mid + 1;                        }                  }                  if(flag) {                        printf("%lld\n", left);                  }            }      }      return 0;}


原创粉丝点击