C语言(7)--高精度加法、减法、乘法、今天是星期几、四位平方数、候选人选票问题

1.高精度加法、减法、乘法

/*
因为计算大数除法时需要用到乘法和减法,
但是不指定字符串长度的乘法和减法不容易用字符数组表示,
所以这里就没写用字符数组计算的大数除法。o(╯□╰)o
*/

/***********大数加减乘/仅限正整数***************/
//加法测试:HDU 1002
//减法测试:百练OJ 2736
//乘法测试:百练OJ 2980

#include <cstdio>
#include <cstring>
#include <malloc.h>
#include <algorithm>
#include <climits>
#include <cmath>
using namespace std;
const int MAX_N=100010;

char a[MAX_N],b[MAX_N],ope[10],ans[MAX_N];
int data[MAX_N];

void Big_Plus()
{
	int lena=strlen(a),lenb=strlen(b);
	if(lena>=lenb){//a位数比b多 
		for(int i=lenb;i>=0;i--)//遍历b中所有元素 
			b[i+(lena-lenb)]=b[i];//数字后移,使末位与a对其 
		for(int i=0;i<lena-lenb;i++)//将数字b中高位上多出来的部分遍历赋0 
			b[i]='0';
	} else{
		for(int i=lena;i>=0;i--)
			a[i+(lenb-lena)]=a[i];
		for(int i=0;i<lenb-lena;i++)
			a[i]='0';
	}
	int carry=0,lenans=max(lena,lenb);
	ans[lenans]='\0';//添加结束符
	int tmp=lenans-1;
	while(tmp>=0){//循环条件;a和b对应位上数字加完 
		int x=a[tmp]-'0';
		int y=b[tmp]-'0';
		int z=x+y+carry;
		if(z>=10) carry=z/10;
		else carry=0;
		z%=10;
		ans[tmp]=z+'0';
		tmp--;
	}
	if(carry){//最高位计算完仍有进位
		for(int i=lenans;i>=0;i--)//lenans是考虑到结束符
			ans[i+1]=ans[i];	//后移 
		ans[0]=carry+'0';	//最高位为carry
	}
}

void Big_Sub()
{
	int lena=strlen(a);//ca为a的长度 
	int lenb=strlen(b);//cb为b的长度 
	if(lena>lenb||lena==lenb&&strcmp(a,b)>=0){ //a的长度大于b或a的长度等于b且字符串a>=b ,结果为正
		int i,j;
		for(i=lena-1,j=lenb-1;j>=0;i--,j--)	//遍历a与b公共长度个字符数字 
			a[i]-=(b[j]-'0');	//计算其结果 
		for(i=lena-1;i>=0;i--){		//遍历a的所有下标 
			if(a[i]<'0'){	//如果当前下标对应值小于0,则借位操作 
				a[i]+=10;	//当前值加10 
				a[i-1]--;	//高位减1 
			}
		}
		i=0;
		//去除前导0
		while(a[i]=='0'&&i<lena-1) i++;
		strcpy(ans,a+i);//将结果复制到ans数组
	} else {//类似上面部分 
		int i,j;
		for(i=lena-1,j=lenb-1;i>=0;i--,j--)
			b[j]-=(a[i]-'0');
		for(j=lenb-1;j>=0;j--){
			if(b[j]<'0'){
				b[j]+=10;
				b[j-1]--;	
			}
		}
		j=0;
		while(b[j]=='0'&&j<lenb-1) j++;
		ans[0]='-';//运算结果为负 
		strcpy(ans+1,b+j);
	}
}

void Big_Mul()
{
	int lena=strlen(a),lenb=strlen(b); 
	int lenans=lena+lenb-1;
	for(int i=0;i<=(lena-1)/2;i++) swap(a[i],a[lena-1-i]); //数组逆置
	for(int i=0;i<=(lenb-1)/2;i++) swap(b[i],b[lenb-1-i]);
	memset(data,0,sizeof(data));
	for(int i=0;i<lena;i++){
		for(int j=0;j<lenb;j++)
			data[i+j]+=(a[i]-'0')*(b[j]-'0'); 	//模拟乘法,计算每一位
	}
	int carry=0;	
	for(int i=0;i<lenans;i++){
		int tmp=data[i]+carry;
		carry=tmp/10;
		data[i]=tmp%10;
	}
	while(carry){
		data[lenans++]=carry%10;
		carry/=10;
	}
	while(data[lenans-1]==0&&lenans>1) lenans--;
	for(int i=0;i<=lenans-1;i++) ans[i]=data[lenans-1-i]+'0';
	ans[lenans]='\0';	//添加结束符
}

int main()
{
	freopen("BigIntin.txt","r",stdin);
	//输入:运算数和运算符之间有空格
	while(~scanf("%s%s%s",a,ope,b))
	{
		printf("%s%s%s=",a,ope,b);
		if(ope[0]=='+'){
			Big_Plus();
		}else if(ope[0]=='-'){
			Big_Sub();
		}else if(ope[0]=='*'){
			Big_Mul();
		}
		puts(ans);
	}
    return 0;
}

2.今天是星期几

要求:输入有效日期,判断当天是星期几

思路:计算距离公元元年1月1日的天数 ,除以7求余转换为星期几

#include <stdio.h>
#include <stdlib.h>
char date[7][7]={"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
int IsLeapYear(int year)
{
	if(year%4==0&&year%100!=0||year%400==0)
		return 1;
	else
		return 0;
}
int main()
{
	int year,month,day;
	int year1[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
	int year2[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
	int days=0,k=0,j=0;//days为距离公元第一天的天数
	char *getDate;
	while(scanf("%d %d %d",&year,&month,&day)!=EOF)
	{
	for(k=1;k<year;k++){//计算与公元第一天相隔的天数
		if(IsLeapYear(k))
			days+=366;
		else
			days+=365; 
	} 
	for(j=1;j<month;j++){
		if(IsLeapYear(year))
			days+=year2[j];
		else
			days+=year1[j];
	}
	days+=day;//加上本年本月过去的天数
	getDate=date[(days)%7];//除以7求余
	printf("%s\n",getDate); 
	days=0;
	}
	system("pause");
    return 0;
} 
运行:



3.四位平方数

求一个四位平方数且该数前两位数字相同,后两位数字也相同且相互之间又不相同

#include <stdio.h>
int issquare(int n);
int main()
{
	int a,b,num;
	for(a=1;a<=9;a++){//前两位数 
		for(b=0;b<=9;b++){//后两位数 
			num=a*1000+a*100+b*10+b;//当前a,b对应的数字 
			if(issquare(num)&&a!=b)
				printf("%d\n",num);
		}
	}
    return 0;
}
int issquare(int n)//判断一个数是否是一个整数平方的函数 
{
	int i,sum=0;
	for(i=1;;i+=2){//平方数的一个特性是n^2=1+3+5+...+(2*n-1) 
		sum+=i;
		if(sum>=n)	break;
	}
	if(sum==n)
		return 1;
	else
		return 0;
}

运行:



4.候选人选票问题

设有代号为"a","b","c"的三个足球先生候选人,根据投票者在选票上对他们编号的填写顺序分别计分为5,3,2。请编程从键盘上输入投票人数和投票结果,统计他们的得分,并输出哪位当选足球先生。请注意:若同一张票上写有两个相同的代号,则显示“此票无效”,若最终前两名得分相同,应显示“重新投票”,否则显示三个候选人得分并输出“祝贺xx当选足球先生!”


思路:(1)候选人结构体构造
(2)投票
(3)统计得分并排序
(4)判断,显示结果 


#include <stdio.h>
#include <stdlib.h>
#define M 100  //投票人数上限
#define N 3    //候选人人数
struct CAN{
	char code;  //代号
	int score;  //得分 
}can[N],st;
int main()
{
	int n,c=0;//n是实际投票人数,c是有效票数
	int i,j,k;
	char temp[N+1];//存放投票的中间变量 
	int s[N]={5,3,2};
	for(i=0;i<N;i++)
	{
		printf("输入第%d个候选人的代号:",i+1);
		scanf("%c",&can[i].code);//输入候选人字符代号
		fflush(stdin);//清除回车符
		can[i].score=0; 
	} 
	printf("输入投票人数:");
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		printf("输入第%d张选票:",i+1);
		scanf("%s",&temp);
		if(temp[0]==temp[1]||temp[1]==temp[2]||temp[0]==temp[2])//无效投票 
			printf("该票无效:%s\n",temp);
		else{
			c++;//有效投票数加1
			for(j=0;j<N;j++){//遍历查找 
				for(k=0;k<N;k++)
					if(can[k].code==temp[j])
						can[k].score+=s[j];//得分累加 
			} 
		}
	}
	for(i=0;i<N-1;i++)//得分排序:选择排序法
	{
		k=i;
		for(j=i+1;j<N;j++){
			if(can[j].score>can[k].score)
				k=j;
		}
		st=can[i];
		can[i]=can[k];
		can[k]=st;
	} 
	if(can[0].score==can[1].score)
		printf("前两名得分相同,都是%d分,请重新投票!\n",can[0].score);
	else{
		printf("候选人\t得分\n");
		for(i=0;i<N;i++)
			printf("%c\t%d\n",can[i].code,can[i].score);
		printf("祝贺%c当选足球先生!\n",can[0].code);
	}
	system("pause");
    return 0;
}


运行:



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值