1015 计算器的改良 (200行代码解决;巨捞;巨烦)

1015 计算器的改良

 

2000年NOIP全国联赛普及组

 时间限制: 1 s

 空间限制: 128000 KB

 题目等级 : 白银 Silver

题解

题目描述 Description

NCL是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手ZL先生。为了很好的完成这个任务,ZL先生首先研究了一些一元一次方程的实例:

 

   4+3x=8

   6a-5+1=2-2a

5+12y=0

 

ZL先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及+、-、=这三个数学符号(当然,符号“─”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。

 

编写程序,解输入的一元一次方程, 将解方程的结果(精确至小数点后三位)输出至屏幕。

 

    你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。

输入描述 Input Description

一个一元一次方程

输出描述 Output Description

方程的解

样例输入 Sample Input

6a-5+1=2-2a

样例输出 Sample Output

a=0.750

数据范围及提示 Data Size & Hint

注意加减号都是半角

//可以先遍历一遍找出哪个小写字母
//表示负数的只能出现在第一个和等号后一个
//字母前面那个数是做的乘法
#include<stdio.h>
#include<string.h>
#define maxn 500
int main (void)
{
	int len,sub_equal,sub_x,sum,res_x1,len_equ_num1,res_num1,res_x2,len_equ_num2,res_num2,res_num,res_x;
	int i,j,i1,j1,i2,j2,i3,j3,i4,j4,i5,j5,i6,j6,i7,j7;
	double result; 
	char equ[maxn],equ1[maxn],equ_num1[maxn],equ2[maxn],equ_num2[maxn];
	char x,sym_x;
	scanf ("%s",equ);
	getchar ();
	len=strlen(equ);
	if (equ[0]!='+'&&equ[0]!='-') {
		for (i3=0;i3<len;i3++) {
			equ1[i3+1]=equ[i3];
		}
		equ1[len+1]='\0';
		equ1[0]='+';
		strcpy(equ,equ1);
	}
	//printf ("%s\n",equ)
	len=strlen(equ);
	//printf ("%s",equ1);
	for (i=0;i<len;i++) {
		if (equ[i]>='a'&&equ[i]<='z') {
			x=equ[i];
			break;
		}
	}
	//printf ("%d123%c",len,x);
	for (j=0;j<len;j++) {
		if (equ[j]=='=') {
			sub_equal=j;
			break;
		}
	}
	strcpy(equ2,equ);
	res_x1=0;
	//对第一段的字母处理 
	for (i1=0;i1<sub_equal;i1++) {
		if (equ[i1]==x) {
			equ[i1]='$'; 
			sum=0;
			for (j1=i1-1;equ[j1]>='0'&&equ[j1]<='9';j1--) {
					;
			}
			sym_x=equ[j1];
			//printf ("%d\n",j1);
			for (i2=j1+1;i2<i1;i2++) {
				sum=sum*10+(equ[i2]-'0');
				equ[i2]='$';
			}
			//printf ("%d\t",sum);
			//printf ("%c\n",sym_x);
			if (sym_x=='-') {
				res_x1-=sum;
			} else {
				res_x1+=sum;
			}
		}
	}
	//printf ("%d\n",res_x1);
	//printf ("%s\n",equ);
	//接下来对数字进行处理
	//我们先找符号 符号前面(等号也算)如果不是字母说明
	//不对 想一下 现在对字母处理过了 能不能把字母那一块全去掉?
	//把除了字母和所带符号之外的东西放入新的字符串 
	//还是不对 字母前可能有数字 这样还是便麻烦了 md真的烦
	//还是走老路 从第二个符号开始 如果前一个不是字母 就是数字  
	//不行 考虑到还有可能没有第二个 还是得写入
	//这样可以把x与前面系数变成$ 但是符号没变
	for (j3=0;j3<len;j3++) {
		if (equ[j3]=='$'&&(equ[j3-1]=='+'||equ[j3-1]=='-')) {
			equ[j3-1]='$';
		}
	} 
	//printf ("%s\n",equ);
	//此时所有不需要的都是$ 接下来我们把这个字符串写入新的 
	j4=0;
	for (i4=0;i4<=sub_equal;i4++) {
		if (equ[i4]!='$') {
			equ_num1[j4++]=equ[i4];
		}
	} 
	equ_num1[j4]='\0'; 
	//printf ("%s\n",equ_num1);
	//至此 把等号前的与数字有关的放入了数组
	//剩下的明天来
	//目前在算出左边的数字结果后 最重要的是怎么处理右边的
	//也许可以在最开始加一个+ 最后面填一个等于好
	//反正优化是不会优化了 复制粘贴注意不要出错 
	//如何处理数字?从开始遍历在符号之间经行得出数字
	len_equ_num1=strlen(equ_num1);
	res_num1=0;
	for (i5=0;i5<len_equ_num1;i5++) {
		if (equ_num1[i5]=='+'||equ_num1[i5]=='-') {
			sum=0;
			for (j5=i5+1;equ_num1[j5]>='0'&&equ_num1[j5]<='9';j5++) {
				sum=sum*10+equ_num1[j5]-'0';
			}
			//printf ("%d\n",sum);
			if (equ_num1[i5]=='+') {
				res_num1+=sum;
			} else {
				res_num1-=sum;
			}
			//printf ("%d\n",res_num1);
		}
	}
	//至此 左半边全部处理完毕 未知数参数为res_x 数字参数为res_num1
	//接下来开始处理有右半边 还是那句话 复制粘贴 注意每一项参数改变 
	//先修改右边等式
	equ2[len]='=';
	equ2[len+1]='\0';
	//printf ("%s\n",equ2);
	//接下来放入第一个加号(如果第一个不是符号)
	if (equ2[sub_equal+1]=='-') {
		i6=0;
	} else {
		i6=1;
		equ1[0]='+';
	}
	for (i7=sub_equal+1;equ2[i7]!='\0';i7++) {
		equ1[i6++]=equ2[i7];
	}
	equ1[i6]='\0';
	//printf ("%s\n",equ1);
	strcpy(equ,equ1);
	//至此equ中存放的是后半端 且被处理过 接下来 开始复制代码
	sub_equal=i6-1;
	len=strlen(equ);
	res_x2=0;
	//对第一段的字母处理 
	for (i1=0;i1<sub_equal;i1++) {
		if (equ[i1]==x) {
			equ[i1]='$'; 
			sum=0;
			for (j1=i1-1;equ[j1]>='0'&&equ[j1]<='9';j1--) {
					;
			}
			sym_x=equ[j1];
			//printf ("%d\n",j1);
			for (i2=j1+1;i2<i1;i2++) {
				sum=sum*10+(equ[i2]-'0');
				equ[i2]='$';
			}
			//printf ("%d\t",sum);
			//printf ("%c\n",sym_x);
			if (sym_x=='-') {
				res_x2-=sum;
			} else {
				res_x2+=sum;
			}
			//printf ("%d**\n",res_x2);
		}
	}
//	printf ("%d\n",res_x2);
	//printf ("%s\n",equ);
	for (j3=0;j3<len;j3++) {
		if (equ[j3]=='$'&&(equ[j3-1]=='+'||equ[j3-1]=='-')) {
			equ[j3-1]='$';
		}
	} 
	//printf ("%s\n",equ);
	//此时所有不需要的都是$ 接下来我们把这个字符串写入新的 
	j4=0;
	for (i4=0;i4<=sub_equal;i4++) {
		if (equ[i4]!='$') {
			equ_num2[j4++]=equ[i4];
		}
	} 
	equ_num2[j4]='\0'; 
	len_equ_num2=strlen(equ_num2);
	res_num2=0;
	for (i5=0;i5<len_equ_num2;i5++) {
		if (equ_num2[i5]=='+'||equ_num2[i5]=='-') {
			sum=0;
			for (j5=i5+1;equ_num2[j5]>='0'&&equ_num2[j5]<='9';j5++) {
				sum=sum*10+equ_num2[j5]-'0';
			}
			//printf ("%d\n",sum);
			if (equ_num2[i5]=='+') {
				res_num2+=sum;
			} else {
				res_num2-=sum;
			}
			//printf ("%d\n",res_num2);
		}
	}
	//至此所有该处理的都处理了 开始算结果
	//上天保佑 千万别错了
	res_x=res_x1-res_x2;
	res_num=res_num2-res_num1;
	//printf ("%d %d",res_x,res_num);
	result=(double)res_num/res_x;
	printf ("%c=%.3lf",x,result);	
	return 0; 
} 

这道题毫无价值,但做一做,很可以磨磨性子

——我是太阳骑士索拉尔,愿阳光永照心中

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值