目录
1.Perfect Sequence
10的9次方-10的18次方之间的数据就要用long long了,注意两个int相乘最后生成一个long long类型的情况。一定要注意,有的地方用了longlong,结果后面又用int进行计算。
二分其实精髓就在于left和right两个变量,left变量一直代表的都是无法达成目标的位置,而right变量一旦移动,那就代表了满足想要的坐标。所以有时候要特判一下right没有移动的情况,本体就是get_num函数的第二行。
因为要找第一个大于某个数的位置,left之前一直都是代表小于或等于。但是left每次都会加1,所以如果加1只有,left碰到right了,说明找到位置了。
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
long long martix[100005];
long long n;
int get_num(int pos,long long value){
int left=pos,right=n,mid;
if(martix[n-1]<=value) return n-pos+1;
while(left<right){
mid = (left+right)/2;
if(martix[mid]<=value){
left=mid+1;
}else{
right=mid;
}
}
return right-pos+1;
}
int main(){
long long p;
scanf("%lld %lld",&n,&p);
for(int i=0;i<n;i++){
scanf("%lld",&martix[i]);
}
sort(martix,martix+n);
int max_=1,cur;
for(int i=0;i<n;i++){
cur=get_num(i+1,martix[i]*p);
if(cur>max_) max_=cur;
}
printf("%d",max_);
return 0;
}
2.Radix
这一题也比较复杂,没有完全解决,思路差不多通了。
这个init函数有点意思,这样初始化数组之后后面就很方便。
整个题的大概流程:
首先是把给出进制的那个数转换成十进制数,如果tag是1那就第一个,如果tag是2,那就把1和2交换一下,用到了strcpy函数。
然后就要大概的算下另外一个数的进制的可能的范围。
(1)下界就用这个数所有位中最大的那一位+1;
(2)上界用下界+1和另外一个给出进制数的十进制数+1的最大值作为上界,这个地方要好好琢么一下
最后就通过进制的范围进行二分,找出来正确的进制。二分时就是选择一个mid的进制,算出这个进制下的十进制形式数字。如果 这个数字大于题目给出的那个进制数的十进制,那么说明我们的进制选大了,righ=mid-1,反之就是left=mid+1;
但是在转换成十进制时需要注意一个问题,那就是可能有时候会溢出,需要特判一下,如果溢出没那么说明肯定很大了,这个进制就太大了,需要right=mid-1;
整理思路大概这样,但是实现起来还是比较繁琐。
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
ll maps[256];
ll inf=(1ll<<43)-1;
void init(){
for(char c='0';c<='9';c++){
maps[c]=c-'0';
}
for(char c='a';c<='z';c++){
maps[c]=c-'a'+10;
}
}
ll convert_to_10(char martix[],ll radix,ll biggest_bound){
ll ans=0;
int len=strlen(martix);
for(int i=0;i<len;i++){
ans = ans*radix+maps[martix[i]];
if(ans<0||ans>biggest_bound) return -1;
}
return ans;
}
int cmp(char martix[],ll radix,ll value){
int len=strlen(martix);
ll martix_num=convert_to_10(martix,radix,value);
if(martix_num<0) return 1;
if(value>martix_num) return -1;
else if(value==martix_num) return 0;
else return 1;
}
ll binarysearch(char martix[],ll left,ll right,ll value){
ll mid;
while(left<=right){
mid = (left+right)/2;
int flag=cmp(martix,mid,value);
if(flag==0) return mid;
else if(flag==-1) left=mid+1;
else right=mid-1;
}
return -1;
}
ll findlargestdigit(char martix[]){
long long ans=-1;
int len=strlen(martix);
for(int i=0;i<len;i++){
if(maps[martix[i]]>ans) ans=martix[i];
}
return ans+1;
}
int main(){
init();
char str1[20],str2[20],temp[20];
int tag,radix;
scanf("%s %s %d %d",str1,str2,&tag,&radix);
//不管怎么样,都让str1成为那个已知进制的数
if(tag==2){
strcpy(temp,str1);
strcpy(str1,str2);
strcpy(str2,temp);
}
//将str1变成十进制
ll str1_10 = convert_to_10(str1,radix,inf);
//找出str2中数位最大的那一个,加上1作为二分查找的下界
ll low_radix=findlargestdigit(str2);
//上界我也有点迷糊
//上界的范围肯定要比下界高1,肯定要比十进制的自己要高1
ll high_radix=max(low_radix,str1_10)+1;
//在下界和上界之间找到正确的
ll ans=binarysearch(str2,low_radix,high_radix,str1_10);
if(ans==-1) printf("Impossible");
else printf("%lld",ans);
return 0;
}
3.Shopping in Mars
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
int martix[100005];
int binary(int left,int right,int value){
int mid;
int lvalue=martix[left-1];
while(left<=right){
mid=(left+right)/2;
if(martix[mid]-lvalue>value){
right=mid-1;
}else if(martix[mid]-lvalue<value){
left=mid+1;
}else{
return mid;
}
}
return -1;
}
int binary2(int left,int right,int value){
int mid;
int lvalue=martix[left-1];
while(left<right){
mid=(left+right)/2;
if(martix[mid]-lvalue>value){
right=mid;
}else{
left=mid+1;
}
}
if(martix[right]-lvalue>value){
return right;
}else{
return -1;
}
}
int main(){
int n,m;
scanf("%d %d",&n,&m);
int temp;
for(int i=1;i<=n;i++){
scanf("%d",&temp);
martix[i]=martix[i-1]+temp;
}
int pos;
bool flag=false;
for(int i=1;i<=n;i++){
pos=binary(i,n,m);
if(pos!=-1){
flag=true;
printf("%d-%d\n",i,pos);
}
}
int min_value=1000000000;
if(!flag){
for(int i=1;i<=n;i++){
pos=binary2(i,n,m);
if(pos!=-1){
if(martix[pos]-martix[i-1]<min_value){
min_value=martix[pos]-martix[i-1];
}
}
}
for(int i=1;i<=n;i++){
pos=binary2(i,n,m);
if(martix[pos]-martix[i-1]==min_value){
printf("%d-%d\n",i,pos);
}
}
}
return 0;
}
4.Find Coins
这个做法有两个点无法通过
#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
int martix[100005];
int n,m;
int getp(int l){
int value=m-martix[l];
int left=l,mid,right=n-1;
while(left<=right){
mid=(left+right)/2;
if(martix[mid]>value){
right=mid-1;
}else if(martix[mid]<value){
left=mid+1;
}else return mid;
}
return -1;
}
int main(){
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&martix[i]);
}
sort(martix,martix+n);
int pos;
bool flag=false;
for(int i=0;i<n;i++){
pos=getp(i);
if(pos!=-1&&pos!=i){
flag=true;
printf("%d %d",martix[i],martix[pos]);
break;
}
}
if(!flag) printf("No solution");
return 0;
}