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;
}