Day 24 算法笔记之算法初步4.5 二分

目录

1.二分查找

2.快速幂

3.完美数列

4.radix


1.二分查找

注意几个地方的判断条件,改一改就是二分查找的模板

#include <cstdio>
#include <cctype>
#include <cstring>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

int f(int a[],int left,int right,int x){
	int mid;
	while(left<=right){
		mid = (left+right)/2;
		if(a[mid]==x){
			return mid;
		}else if(a[mid]>x){
			right = mid-1;
		}else{
			left = mid +1;
		}
	}
	return -1;
}

int main(){
	
	int n = 10;
	int a[n] = {1,3,4,6,7,8,10,11,12,15};
	printf("%d %d\n",f(a,0,n-1,6),f(a,0,n-1,19));
	
	return 0;
}

2.快速幂

//递归
typedef long long ll;

ll f(ll a,ll b,ll m){
	if(b==0){
		return 1;
	}
	if(b%2==1){
		return a*f(a,b-1,m)%m;
	}else{
		ll mul = f(a,b/2,m);
		return mul*mul%m;
	}
}

//迭代
typedef long long ll;
ll f(ll a,ll b,ll m){
	ll ans=1;
	while(b>0){
		if(b&1){
			ans = ans*a%m;
		}
		a = a*a%m;
		b>>=1;
	}
}

3.完美数列

#include <cstdio>
#include <cctype>
#include <cstring>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

int n,p;
int martix[10000];

bool cmp(int a,int b){
	return a<b;
}

int f(int pos,int value){
	if(martix[n-1]<=value){
		return n;
	}
	
	int left = pos+1,right= n-1,mid;
	
	while(left<right){
		mid = (left+right)/2;
		if(martix[mid]>value){
			right = mid;
		}else{
			left = mid + 1;
		}
	}
	
	return left;
}

int main(){

	scanf("%d %d",&n,&p);
	

	for(int i=0;i<n;i++){
		scanf("%d",&martix[i]);
	}
	
	sort(martix,martix+n,cmp);
	
	int ans=1;
	int temp;
	
	for(int i=0;i<n;i++){
		temp = f(i,martix[i]*p);
		ans = max(ans,temp-i);
	}
	
	printf("%d\n",ans);
	return 0;
}

4.radix

这题主要麻烦在进制的转换,以及进制的范围的确定

#include <cstdio>
#include <cctype>
#include <cstring>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

typedef long long ll;

ll maps[256];
ll inf = 10000000000;

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 convertnum10(char a[],ll radix,ll t){
	ll ans=0;
	int len = strlen(a);
	
	for(int i=0;i<len;i++){
		ans = ans*radix+maps[a[i]];
		if(ans<0||ans>t){
			return -1;
		}
	}
	
	return ans;
}

int findlargestdigit(char n2[]){
	int ans = -1,len = strlen(n2);
	for(int i = 0;i<len;i++){
		if(maps[n2[i]]>ans){
			ans = maps[n2[i]];
		}
	}
	return ans+1;
}

int cmp(char n2[],ll radix, ll t){
	int len = strlen(n2);
	int num = convertnum10(n2,radix,t);
	if(num<0){
		return 1;
	}
	if(t>num) return -1;
	else if(t==num) return 0;
	else return 1;
}


ll binarysearch(char n2[],ll left,ll right,ll t){
	ll mid;
	while(left<=right){
		mid = (right+left)/2;
		int flag = cmp(n2,mid,t);
		if(flag==0){
			return mid;
		}
		else if(flag == -1){
			left = mid+1;
		}else{
			right = mid -1;
		}
	}
	return -1;
}

int main(){
	
	init();
	
	char n1[20],n2[20],temp[20];
	int tag,radix;
	scanf("%s %s %d %d",n1,n2,&tag,&radix);
	
	if(tag==2){
		strcpy(temp,n1);
		strcpy(n1,n2);
		strcpy(n2,temp);
	}
	
	ll t = convertnum10(n1,radix,inf);
	ll low = findlargestdigit(n2);
	ll high = max(low,t)+1;
	ll ans = binarysearch(n2,low,high,t);
	
	if(ans==-1){
		printf("Impossible\n");
	}else{
		printf("%lld\n",ans);
	}

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值