2005年百度之星程序设计大赛试题初赛题目二的解答(重叠区间大小)

来源:互联网 发布:php互联网工程师证书 编辑:程序博客网 时间:2024/05/08 22:55

第二题(共四题 100 分):重叠区间大小( 20 分)
题目描述:请编写程序,找出下面 “ 输入数据及格式 ” 中所描述的输入数据文件中最大重叠区间的大小。
对一个正整数 n ,如果 n 在数据文件中某行的两个正整数(假设为 A 和 B )之间,即 A<=n<=B 或 A>=n>=B ,则 n 属于该行;如果 n 同时属于行 i 和 j ,则 i 和 j 有重叠区间;重叠区间的大小是同时属于行 i 和 j 的整数个数。
例如,行( 10 20 )和( 12 25 )的重叠区间为 [12 20] ,其大小为 9 ;行( 20 10 )和( 12 18 )的重叠区间为 [10 12] ,其大小为 3 ;行 (20 10) 和( 20 30 )的重叠区间大小为 1 。
输入数据:程序读入已被命名为 input.txt 的输入数据文本文件,该文件的行数在 1 到 1,000,000 之间,每行有用一个空格分隔的 2 个正整数,这 2 个正整数的大小次序随机,每个数都在 1 和 2^32-1 之间。(为便于调试,您可下载测试 input.txt 文件,实际运行时我们会使用不同内容的输入文件。)
输出数据:在标准输出上打印出输入数据文件中最大重叠区间的大小,如果所有行都没有重叠区间,则输出 0 。
评分标准:程序输出结果必须正确,内存使用必须不超过 256MB ,程序的执行时间越快越好。

#include "iostream.h"
#include "fstream"
#include "vector"
#include "string"
#include "utility"
#include "map"
#define   MIN     0

using namespace std;

bool IsLegal(char *str)//检查是否有非法字符
{
 char *p;
 for (p=str;*p!=0;++p)//如果有非0字符
 {
  if (!(*p>='0'&&*p<='9')&& *p!=' ')
  {
  return false;
  }
 }
 
 return true;
}

int  NumInts(char *str,int (&ints)[10])//检查数字的个数,并把他们取出放到ints数组中
{
 char *p=str;
 int result=0;
 bool IsBeforBlack=true;//前面一个是否是空格,如果是空格为true,此时是一个新的数


 while (*p!=NULL)
 { 
  if (*p==' ')//如果等于空格
  {
   IsBeforBlack=true;
  }
  else if (*p!=' ')//如果不等于空格
  {
   if (IsBeforBlack==true)//如果前面一个是空格
   {
    ints[result]=atoi(p);
    result++;
    IsBeforBlack=false;
   }
  }
  p++;
 }
 return result;
}

bool  IsPositive(int ints[2])//判断是否数组中的数字是否正数
{
 bool result=true;
 for (int i=0;i<2;i++)
 {
  if (ints[i]<=0)
  {
   result=false;
   return result;
  }
 }

   return result;
}

 

 


bool MAKEPAIR(char *str,pair<int,int> &mypair)//从字符串中提取2个int放到传入的mypair中。
{
 char *p=str;
 int i=0,j=0;
 int ints[10];

 
 if (!strcmp(str," "))
 {
     cout<<"输入文件中含有空行,或者是空文件"<<endl;
  return  false;
 }
 

 if (!IsLegal(str))//如果含有非法字符
 {
  cout<<"输入文件中含有非法字符(非数字和空格)"<<endl;
  return  false;
 }
 
 if (NumInts(str,ints)!=2)//如果数字个数不是2
 {
  cout<<"输入的数字个数不合法(不是2个)"<<endl;
  return false;
 }

 if (!IsPositive(ints))//如果2个数字中有一个以上不是正数
 {
  cout<<"输入的数字有不是正数"<<endl;
  return false;
 }

 mypair.first=(ints[0]<=ints[1]?ints[0]:ints[1]);//将较小的值放入到pair<x,y>中的x
 mypair.second=(ints[0]<=ints[1]?ints[1]:ints[0]);
 
 return true;
}

 

bool readfromfile(multimap<int,int> &mymultimap)//从文件中读取所有的行,放入到multimaps<int,int>中。
{
 string str;
 str="D://input.txt";
    pair<int ,int> mypair;

 char temp[10];
 ifstream infile;
 infile.open(str.c_str(),ios::out );
 if (!infile.is_open())
 {
  cout<<"文件打开失败"<<endl;
  return   false;
 }
 while (!infile.eof())
 {
  infile.getline(temp,10);
        if(!MAKEPAIR(temp,mypair))
  { 
   infile.close();
         return false;
  }
  mymultimap.insert(mypair);
 }
 infile.close();
    return true;
}

int min(int a,int b)
{
 return   a>=b?  b:a;

}

int max (int a,int b)
{
 return a>=b?  a:b;
}

void main()
{
 multimap<int,int> mymultimap; 
    if(!readfromfile(mymultimap))
 {
  return;
 }
 bool IsFind=false;//用来表示是否找到重叠区间
 int  length=MIN;//用来表示最大重叠区间大小
 
 multimap<int,int>::iterator myiter=mymultimap.begin ();
 for (;myiter!=mymultimap.end ();++myiter)//输出所有的pair
 {
  cout<<myiter->first <<"/t"<<myiter->second <<endl;
 }
 
 multimap<int,int>::iterator myiter2=mymultimap.begin ();
 for (myiter=mymultimap.begin();myiter!=mymultimap.end ();++myiter)
 {   
  myiter2=myiter;
  myiter2++;
  for (;myiter2!=mymultimap.end ();++myiter2)
  {  
   length=length<(min(myiter->second,myiter2->second)-max(myiter->first,myiter2->first))?(min(myiter->second,myiter2->second)-max(myiter->first,myiter2->first)):length;
  }
  
 }
 
 if (length==MIN)
 {
  cout<<MIN;
 }
 
 else
  cout<<"重叠区间大小是:"<<length+1<<endl;

 
}

 

原创粉丝点击