PAT 1010 Radix (25)
2015-06-30 22:01
357 查看
先看题目:
这个题目算是比较DT,花了很长时间,提交次数很多,每次都会有测试点没通过,后来网上搜索了一下,有一些特俗边界条件被我们忽略。
1,首先求目标数据进制,这个进制在任何条件下面都不能小于2,最大多少呢,不能局限于36,请想象多大都是有可能的,有多大,这么大!所以必须用long long int数据类型,这个一开始一直是被遗忘的角落。
2,由于数据搜索范围太大,穷举法一个for循环显然太慢了,肯定要超时的,最终就选则二分法查找。那么问题来了,二分法查找搜索上下边界是多少呢。这个好办,目标待求字符串的最小进制一定要比它所包含字符最大值还要大1,例如N2="456ad",最大字符是'd',所以最小应该是13+1=14,,这就对了吗?当然不对万一,我输入的N2="0"呢
最大字符'0',然后0+1=1,这是不对的,最小值是2才对。那么它的上限是多少呢,上限当然不能超过另外一个数据的十进制大小,因为N2不为0情况下,最小个位数都是1,如果它的进制再超过N1的十进制数了的话,它在十进制下的数也就比N1还要大,不符合要求。
3,如果一开始,输入两个数据N2最小进制都比N1的十进制数据还要大的话,怎么办呢。N2最小进制的最大数据也就36,出现这种情况也就说明N1在十进制下肯定比36小,二分查找上限就不能是N1在十进制时候的数了,应该改为36。
几个特俗测试点容易被遗忘 0 0 1 100以及12 c 1 10
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
long long jinzhi(char str[],long long radix);
int maxstr(char str[]);
long long BinSear(long long target,char str[],long long low,long long high);
int compare(char str[],long long radix,long long target);
int main()
{
char N1[11]={0};
char N2[11]={0};
int tag;
long long radix;//此处输入有可能超过int表示范围
cin>>N1>>N2>>tag>>radix;
long long low,high,heji=0;
if(tag==1)
{
heji=jinzhi(N1,radix);
long long temp=(long long)maxstr(N2)+1;//此处temp最小值为2,最大值为36
if(heji<=temp)//如果了heji比temp还要小
{
long long linshi=BinSear(heji,N2,temp,36);//待求进制数介于temp到36之间
if(linshi==-1)
cout<<"Impossible";
else
cout<<linshi;
}
else
{
low=temp;
high=heji+1;
long long result=BinSear(heji,N2,low,high);
if(result==-1)
cout<<"Impossible";
else
cout<<result;
}
}
if(tag==2)
{
heji=jinzhi(N2,radix);
long long temp=(long long)maxstr(N1)+1;//此处temp最小值为2,最大值为36
if(heji<=temp)//如果了heji比temp还要小
{
long long linshi=BinSear(heji,N1,temp,36);//待求进制数介于temp到36之间
if(linshi==-1)
cout<<"Impossible";
else
cout<<linshi;
}
else
{
low=temp;
high=heji+1;
long long result=BinSear(heji,N1,low,high);
if(result==-1)
cout<<"Impossible";
else
cout<<result;
}
}
return 0;
}
int compare(char str[],long long radix,long long target)
{
int length=strlen(str);
long long sum=0;
for(int i=0;i<length;i++)
{
if(str[i]<58)
sum=sum*radix+(str[i]-48);
else
sum=sum*radix+(str[i]-87);
if(sum>target||sum<0)//sum<0是因为有可能目标数太大了,导致long long也不够存储,超过计算机存储范围,就会变为复数
return 1;
}
if(sum>target)
return 1;
else if(sum<target)
return -1;
else
return 0;//sum等于target
}
long long BinSear(long long target,char str[],long long low,long long high)
{
long long mid=low;
while(low<=high)
{
if(compare(str,mid,target)==1)
high=mid-1;
else if(compare(str,mid,target)==-1)
low=mid+1;
else
return mid;
mid=(low+high)/2;//缩小查找范围
}
return -1;
}
long long jinzhi(char str[],long long radix)
{
int length=strlen(str);
long long sum=0;
for(int i=0;i<length;i++)
if(str[i]<58)
sum=sum*radix+(str[i]-48);
else
sum=sum*radix+(str[i]-87);
return sum;
}
int maxstr(char str[])//进制最小数量必须所包含最大数字大1,例如出现有f,则至少是16进制,如出现7,至少是8进制
{
int length=strlen(str);
int max=0;
for(int i=0;i<length;i++)
{
if(str[i]<58&&str[i]-48>max)
max=str[i]-48;
else if(str[i]-87>max)
max=str[i]-87;
}
if(max>1)
return max;
else
return 1;//如果字符串内容全都是0,那么最大值应该是1才对
}
这个题目算是比较DT,花了很长时间,提交次数很多,每次都会有测试点没通过,后来网上搜索了一下,有一些特俗边界条件被我们忽略。
1,首先求目标数据进制,这个进制在任何条件下面都不能小于2,最大多少呢,不能局限于36,请想象多大都是有可能的,有多大,这么大!所以必须用long long int数据类型,这个一开始一直是被遗忘的角落。
2,由于数据搜索范围太大,穷举法一个for循环显然太慢了,肯定要超时的,最终就选则二分法查找。那么问题来了,二分法查找搜索上下边界是多少呢。这个好办,目标待求字符串的最小进制一定要比它所包含字符最大值还要大1,例如N2="456ad",最大字符是'd',所以最小应该是13+1=14,,这就对了吗?当然不对万一,我输入的N2="0"呢
最大字符'0',然后0+1=1,这是不对的,最小值是2才对。那么它的上限是多少呢,上限当然不能超过另外一个数据的十进制大小,因为N2不为0情况下,最小个位数都是1,如果它的进制再超过N1的十进制数了的话,它在十进制下的数也就比N1还要大,不符合要求。
3,如果一开始,输入两个数据N2最小进制都比N1的十进制数据还要大的话,怎么办呢。N2最小进制的最大数据也就36,出现这种情况也就说明N1在十进制下肯定比36小,二分查找上限就不能是N1在十进制时候的数了,应该改为36。
几个特俗测试点容易被遗忘 0 0 1 100以及12 c 1 10
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
long long jinzhi(char str[],long long radix);
int maxstr(char str[]);
long long BinSear(long long target,char str[],long long low,long long high);
int compare(char str[],long long radix,long long target);
int main()
{
char N1[11]={0};
char N2[11]={0};
int tag;
long long radix;//此处输入有可能超过int表示范围
cin>>N1>>N2>>tag>>radix;
long long low,high,heji=0;
if(tag==1)
{
heji=jinzhi(N1,radix);
long long temp=(long long)maxstr(N2)+1;//此处temp最小值为2,最大值为36
if(heji<=temp)//如果了heji比temp还要小
{
long long linshi=BinSear(heji,N2,temp,36);//待求进制数介于temp到36之间
if(linshi==-1)
cout<<"Impossible";
else
cout<<linshi;
}
else
{
low=temp;
high=heji+1;
long long result=BinSear(heji,N2,low,high);
if(result==-1)
cout<<"Impossible";
else
cout<<result;
}
}
if(tag==2)
{
heji=jinzhi(N2,radix);
long long temp=(long long)maxstr(N1)+1;//此处temp最小值为2,最大值为36
if(heji<=temp)//如果了heji比temp还要小
{
long long linshi=BinSear(heji,N1,temp,36);//待求进制数介于temp到36之间
if(linshi==-1)
cout<<"Impossible";
else
cout<<linshi;
}
else
{
low=temp;
high=heji+1;
long long result=BinSear(heji,N1,low,high);
if(result==-1)
cout<<"Impossible";
else
cout<<result;
}
}
return 0;
}
int compare(char str[],long long radix,long long target)
{
int length=strlen(str);
long long sum=0;
for(int i=0;i<length;i++)
{
if(str[i]<58)
sum=sum*radix+(str[i]-48);
else
sum=sum*radix+(str[i]-87);
if(sum>target||sum<0)//sum<0是因为有可能目标数太大了,导致long long也不够存储,超过计算机存储范围,就会变为复数
return 1;
}
if(sum>target)
return 1;
else if(sum<target)
return -1;
else
return 0;//sum等于target
}
long long BinSear(long long target,char str[],long long low,long long high)
{
long long mid=low;
while(low<=high)
{
if(compare(str,mid,target)==1)
high=mid-1;
else if(compare(str,mid,target)==-1)
low=mid+1;
else
return mid;
mid=(low+high)/2;//缩小查找范围
}
return -1;
}
long long jinzhi(char str[],long long radix)
{
int length=strlen(str);
long long sum=0;
for(int i=0;i<length;i++)
if(str[i]<58)
sum=sum*radix+(str[i]-48);
else
sum=sum*radix+(str[i]-87);
return sum;
}
int maxstr(char str[])//进制最小数量必须所包含最大数字大1,例如出现有f,则至少是16进制,如出现7,至少是8进制
{
int length=strlen(str);
int max=0;
for(int i=0;i<length;i++)
{
if(str[i]<58&&str[i]-48>max)
max=str[i]-48;
else if(str[i]-87>max)
max=str[i]-87;
}
if(max>1)
return max;
else
return 1;//如果字符串内容全都是0,那么最大值应该是1才对
}
相关文章推荐
- Android Studio使用技巧
- 内部类相关2
- css3:target页内跳转
- Int.Parse与ConvertToInt的区别
- 【数据库】Oracle vs SQL Server
- Linux C程序调用外部程序的几种方法
- java中key值可以重复的map---IdentityHashMap
- 基于全志A20 android4.2平台如何支持三个SD卡
- 用protractor测试canvas绘制(一)
- github
- 2015面试记三
- SAX解析XML
- Android开源项目分类汇总
- 我的第一个Servlet
- log4j
- Eclipse UML小工具AmaterasUML的配置和使用
- python 优秀文章索引
- 第八十九天 how can I 坚持
- linux下pl330 DMA控制器驱动分析
- 十分简单方便的二维码工具