强化阶段 Day 16 算法笔记 5.1-5.3 简单数学

目录

1.The Black Hole of Numbers

2.最大公约数(欧几里得算法)

3.最小公倍数

4.我要通过!

5.Sum of Number Segments

6.Elevator

7.Counting Ones

8.数组元素循环右移问题

9.分数的定义及化简

10.分数的加减乘除以及输出

11.Rational Sum

12.Rational Arithmetic


1.The Black Hole of Numbers

这一题也是修修补补才做出来,关键在于自己的逻辑是错误的但是却没意识到,所以就只能碰巧通过一些测试点。

更简单的方法应该是拿到这个数字后,先把它变成数组的形式存储,之后分别按非递增和非递减的方式排序并计算大和小的值,再与6174进行比较

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;

int getbig(int x){
	int martix[10]={0};
	while(x!=0){
		martix[x%10]+=1;
		x/=10;
	}
	int ans=0,ratio=1000;
	for(int i=9;i>=0;i--){
		while(martix[i]!=0){
			ans+=i*ratio;
			ratio/=10;
			martix[i]--;
		}
	}
	return ans;
}

int getsmall(int x){
	int martix[10]={0};
	while(x!=0){
		martix[x%10]+=1;
		x/=10;
	}
	int ans=0,ratio=1;
	for(int i=0;i<10;i++){
		while(martix[i]!=0){
			ans=ans*10+i;
			ratio*=10;
			martix[i]--;
		}
	}
	return ans;
}

bool issame(int x){
	int y=x%10;
	for(int i=0;i<4;i++){
		if(y!=x%10) return false;
		x/=10;
	}
	return true;
}

int main(){
	
	int n;
	scanf("%d",&n);
	int big,small;
	while(1){
		if(issame(n)){
			printf("%04d - %04d = %04d",n,n,0);
			return 0;
		}
		big=getbig(n);
		small=getsmall(n);
		n=big-small;
		printf("%04d - %04d = %04d\n",big,small,n);
		if(n==6174) break;
	}
	
	return 0;
}

2.最大公约数(欧几里得算法)

int gab(int a,int b){
	if(b==0) return x;
	else return gab(b,a%b);
}

3.最小公倍数

int lcm(int x){
	return a*b*gcb(a,b);
}

4.我要通过!

看起来很离谱的一个题目,需要仔细观察题目给的式子。

最后可以得出x=z-x*(y-1)这样的关系式

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
 
int main(){
	
	int n;
	scanf("%d",&n);
	while(n--){
		char str[105];
		scanf("%s",str);
		int len=strlen(str);
		int num_p=0,num_t=0,others=0;
		int loc_p=-1,loc_t=-1;
		for(int i=0;i<len;i++){
			if(str[i]=='P'){
				num_p++;
				loc_p=i;
			}else if(str[i]=='T'){
				num_t++;
				loc_t=i;
			}else if(str[i]!='A') others++;
		}
		if((others!=0)||(num_p!=1)||(num_t!=1)||(loc_t-loc_p<=1)){
			printf("NO\n");
			continue;
		}
		int x=loc_p,y=loc_t-loc_p-1,z=len-loc_t-1;
		if(x!=z-x*(y-1)) printf("NO\n");
		else printf("YES\n");
	}
	
	return 0;
}

5.Sum of Number Segments

有一个点无法通过

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
 
int main(){
	
	int n;
	scanf("%d",&n);
	double ans=0,value;
	for(int i=1;i<=n;i++){
		scanf("%lf",&value);
		ans+=value*i*(n-i+1);
	}
	printf("%.2f",ans);
	return 0;
}

6.Elevator

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
 
int main(){
	
	int n;
	scanf("%d",&n);
	int now=0,next,ans=0;
	while(n--){
		scanf("%d",&next);
		if(next>now){
			ans+=(next-now)*6+5;
		}else{
			ans+=(now-next)*4+5;
		}
		now=next;
	}
	printf("%d",ans);
	
	return 0;
}

7.Counting Ones

很有意思的数学问题

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
 
int main(){
	
	int n;
	scanf("%d",&n);
	int a=1,ans=0;
	int left,now,right;
	while(n/a!=0){
		left=n/(a*10);
		now=n/a%10;
		right=n%a;
		if(now==0) ans+=left*a;
		else if(now==1) ans+=left*a+right+1;
		else ans+=(left+1)*a;
		a*=10;
	}
	printf("%d",ans);
	
	return 0;
}

8.数组元素循环右移问题

#include<cstdio>
#include<vector>
#include<cstring>
#include<string>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;

int get_gcb(int x,int y){
	if(y==0) return x;
	else return get_gcb(y,x%y);
}
 
int main(){
	
	int n,m;
	scanf("%d%d",&n,&m);
	int martix[105];
	for(int i=0;i<n;i+=1){
		scanf("%d",&martix[i]);
	}
	m=m%n;
	if(m!=0){
		int gcb=get_gcb(n,m);
		for(int i=n-m;i<=n-m+gcb-1;i++){
			int temp=martix[i];
			int now=i,next;
			do{
				next=(now-m+n)%n;
				if(next!=i) martix[now]=martix[next];
				else martix[now]=temp;
				now=next;
			}while(now!=i);
		}
	}
	for(int i=0;i<n;i++){
		printf("%d",martix[i]);
		if(i!=n-1) printf(" ");
	}
	
	return 0;
}

9.分数的定义及化简

struct fraction{
	int up,down;
};

fraction f(fraction a){
	if(a.down<0){
		a.down=-a.down;
		a.up=-a.up;
	}
	if(a.up==0){
		a.down=1;
	}else{
		int d=gac(a.up,a.down);
		a.up/=d;
		a.down/=d;
	}
	return a;
}

10.分数的加减乘除以及输出

fraction add(fraction a,fraction b){
	fraction result;
	result.up=a.up*b.down+a.down*b.up;
	result.down=a.down*b.down;
	return reduction(result);
}

fraction minu(fraction a,fraction b){
	fraction result;
	result.up=a.up*b.down-a.down*b.up;
	result.down=a.down*b.down;
	return reduction(result);
}

fraction multi(fraction a,fraction b){
	fraction result;
	result.up=a.up*b.up;
	result.down=a.down*b.down;
	return reduction(result);
}

fraction divide(fraction a,fraction b){
	fraction result;
	result.up=a.up*b.down;
	result.down=a.down*b.up;
	return reduction(result);
}

void showresult(fraction r){
	r =reduction(r);
	if(r.down==1) printf("%lld",r.up);
	else if(abs(r.up)>r.down){
		printf("%d %d/%d",r.up/r.down,abs(r.up)%r.down,r.down);
	}else printf("%d/%d",r.up,r.down);
}

11.Rational Sum

#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 gcb(ll x,ll y){
	if(y==0) return x;
	else return gcb(y,x%y);
}

struct fraction{
	ll up,down;
};

fraction reduction(fraction a){
	if(a.down<0){
		a.down=-a.down;
		a.up=-a.up;
	}
	if(a.up==0){
		a.down=1;
	}else{
		int d=gcb(a.up,a.down);
		a.up/=d;
		a.down/=d;
	}
	return a;
}

fraction add(fraction a,fraction b){
	fraction result;
	result.up=a.up*b.down+a.down*b.up;
	result.down=a.down*b.down;
	return reduction(result);
}

void showresult(fraction r){
	r =reduction(r);
	if(r.down==1) printf("%lld",r.up);
	else if(abs(r.up)>r.down){
		printf("%d %d/%d",r.up/r.down,abs(r.up)%r.down,r.down);
	}else printf("%d/%d",r.up,r.down);
}
 
int main(){
	
	int n;
	scanf("%d",&n);
	fraction ans;
	ans.up=0;
	ans.down=1;
	fraction temp;
	for(int i=0;i<n;i++){
		scanf("%lld/%lld",&temp.up,&temp.down);
		ans = add(ans,temp);
	}
	showresult(ans);
	
	return 0;
}

12.Rational Arithmetic

#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 gcb(ll x,ll y){
	if(y==0) return x;
	else return gcb(y,x%y);
}

struct fraction{
	ll up,down;
};

fraction reduction(fraction a){
	if(a.down<0){
		a.down=-a.down;
		a.up=-a.up;
	}
	if(a.up==0){
		a.down=1;
	}else{
		int d=gcb(abs(a.up),abs(a.down));
		a.up/=d;
		a.down/=d;
	}
	return a;
}

fraction add(fraction a,fraction b){
	fraction result;
	result.up=a.up*b.down+a.down*b.up;
	result.down=a.down*b.down;
	return reduction(result);
}

fraction minu(fraction a,fraction b){
	fraction result;
	result.up=a.up*b.down-a.down*b.up;
	result.down=a.down*b.down;
	return reduction(result);
}

fraction multi(fraction a,fraction b){
	fraction result;
	result.up=a.up*b.up;
	result.down=a.down*b.down;
	return reduction(result);
}

fraction divide(fraction a,fraction b){
	fraction result;
	result.up=a.up*b.down;
	result.down=a.down*b.up;
	return reduction(result);
}

void showresult(fraction r){
	r =reduction(r);
	if(r.up<0) printf("(");
	if(r.down==1) printf("%lld",r.up);
	else if(abs(r.up)>r.down){
		printf("%lld %lld/%lld",r.up/r.down,abs(r.up)%r.down,r.down);
	}else printf("%lld/%lld",r.up,r.down);
	if(r.up<0) printf(")");
}

int main(){
	
	fraction a,b;
	scanf("%lld/%lld %lld/%lld",&a.up,&a.down,&b.up,&b.down);
	showresult(a);
	printf(" + ");
	showresult(b);
	printf(" = ");
	showresult(add(a,b));
	printf("\n");
	showresult(a);
	printf(" - ");
	showresult(b);
	printf(" = ");
	showresult(minu(a,b));
	printf("\n");
	showresult(a);
	printf(" * ");
	showresult(b);
	printf(" = ");
	showresult(multi(a,b));
	printf("\n");
	showresult(a);
	printf(" / ");
	showresult(b);
	printf(" = ");
	if(b.up==0) printf("Inf");
	else showresult(divide(a,b));
	
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值