您的位置:首页 > 其它

2015暑假训练题解(二分)

2015-07-13 16:53 232 查看
A题 (poj2503)

这道题很容易就想到枚举,然而枚举会浪费时间。。。所以说这道题先排序,然后再二分,运行速度嗖嗖嗖~

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int mm=100010;
struct node
{
    char e[60],s[60];
}dic[mm];
char t[60];
int pos;
bool cmp(node a,node b)
{
    return strcmp(a.s,b.s)<0;
}
int binserch(char *s)
{
    int l=0,r=pos-1;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(strcmp(dic[mid].s,s)==0) return mid;
        else if(strcmp(dic[mid].s,s)>0) r=mid-1;
        else l=mid+1;
    }
    return -1;
}
int main()
{
    //freopen("in.txt","r",stdin);
    pos=0;
    char z;
    while(~scanf("%s%c",dic[pos].e,&z))
    {
        if(z=='\n')
        {
            strcpy(t,dic[pos].e);
            break;
        }
        scanf("%s",dic[pos++].s);
    }
    sort(dic,dic+pos,cmp);
    int num=binserch(t);
    if(num>=0)
        printf("%s\n",dic[num].e);
    else puts("eh");
    while(~scanf("%s",t))
    {
        num=binserch(t);
        if(num>=0)
            printf("%s\n",dic[num].e);
        else
            puts("eh");
    }
    return 0;
}


B题 (hdu1007)

求平面最近点对距离的一半,同样枚举会超时。

<pre name="code" class="cpp">#include <bits/stdc++.h>
using namespace std;

const int mm=100008;
const double oo=1e100;

struct Point
{
    double x,y;
} poin[mm];

int tmp[mm];
int m;

bool cmpxy(Point a,Point b)    //先对x排序,再对y排序
{
    if(a.x==b.x)
        return a.y<b.y;
    else
        return a.x<b.x;
}

bool cmp(int a,int b)     //对y排序
{
    return poin[a].y<poin[b].y;
}

double dist(Point a,Point b)    //点距离
{
    double dis=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    return sqrt(dis);
}

double min_dist(int left,int right)
{
    double d=oo;
    if(left==right)  return d;
    else if(left+1==right)
        return dist(poin[left],poin[right]);
    int mid=(left+right)/2;
    d=min(min_dist(left,mid),min_dist(mid+1,right));
    int pos=0;
    for(int i=0;i<=right;i++)
    {
        if(fabs(poin[i].x-poin[mid].x)<=d)
            tmp[pos++]=i;
    }
    sort(tmp,tmp+pos,cmp);
    for(int i=0;i<pos;i++)
        for(int j=i+1;j<pos&&poin[tmp[j]].y-poin[tmp[i]].y<=d;j++)
        {
            double dd=dist(poin[tmp[i]],poin[tmp[j]]);
            d=min(d,dd);
        }
    return d;
}

int main()
{
    #ifdef novak
    freopen("in.txt","r",stdin);
    #endif // novak
    while(~scanf("%d",&m))
    {
        for(int i=0;i<m;i++)
            cin>>poin[i].x>>poin[i].y;
        sort(poin,poin+m,cmpxy);
        double ans=min_dist(0,m-1)/2.0;
        printf("%.2lf\n",ans);
    }
    return 0;
}




C题

今天上午说过的,注意count+=floor(len[i]/x);

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
#define PI acos(-1.0)
double len[10001];
int n,f;
bool Get(double x)
{
    int count=0;
    for(int i=0;i<n;i++)
        {
            count+=floor(len[i]/x);
        }
    return count>=f+1;
}
int main(){
    int m;
    cin>>m;
    while(m--){
        cin>>n>>f;
        double l=0,r=0,mid,sum=0;
        for(int i=0;i<n;i++)
        {
            cin>>len[i];
            len[i]=len[i]*len[i]*PI;
            sum+=len[i];
        }
        r=(double)sum/(f+1);
        while(r-l>1e-6)
        {
            mid=double(r+l)/2;
            if(Get(mid))
                l=mid;
            else
                r=mid;
        }
        printf("%.4lf\n",l);
    }
}


D题 (poj2456)

一个最大值最小化的问题,先对牛之间的距离进行排序,由c头牛可知共有c-1个距离区间,所以所求的答案d必定是小于等于相隔最远的两个牛的距离差除以c-1

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mm=100010;
int f[mm];
int n,c;
int main()
{
    #ifdef novak
    freopen("in.txt","r",stdin);
    #endif // novak
    while(~scanf("%d%d",&n,&c))
    {
        for(int i=0;i<n;i++)
            scanf("%d",&f[i]);
        sort(f,f+n);
        c--;
        int left,right,mid,dex,num;
        left=0;
        mid=right=(f[n-1]-f[0])/c;
        while(left<right)
        {
            int i;
            dex=0;num=0;
            for(i=dex+1;i<n;i++)
            {
                if(f[i]-f[dex]>=mid)
                {
                    dex=i;
                    num++;
                    if(num==c)  break;
                }
            }
            if(i==n)
                right=mid-1;
            else
                left=mid;
            mid=(left+right+1)/2;
        }
        printf("%d\n",mid);
    }
    return 0;
}


E题

赤裸裸的最小值最大化问题……

#include <cstdio>
#define MAX 100001

int day[MAX];
int N,M;

int main()
{
    int i,j;
    int sum,cnt,max,low,high,mid;

    while(scanf("%d %d",&N,&M)!=EOF)
    {
       sum = 0;
       max = 0;
       for(i=0;i<N;i++){
             scanf("%d",&day[i]);
             if(day[i]>max)
               max = day[i];
             sum+=day[i];
       }
       low = max;
       high = sum;

       while(low<=high)
       {
          mid = (low+high)/2;

          sum = 0;
          cnt = 1;
          for(i = 0;i<N;i++){
            sum+=day[i];
            if(sum>mid)  {
               sum = day[i];
               cnt++;
             }
          }

          if(cnt<=M)  {
             max = mid;  //一定要记下这个值
             high = mid-1;
          }
          else
             low = mid+1;
       }
       printf("%d\n",max);
    }
    return 0;
}


F、G 两题今天跪了,明天继续出~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: