首先发现,计算机的精度有限,导致 1 / 3 + 1 / 3 + 1 / 3 ! = 1 1/3+1/3+1/3!=1 1/3+1/3+1/3!=1
所以就把1看成1/1
0.5看成1/2 每个运算都是分数的加减法
字符串转数字形式
将字符串转化为数字形式
第一行:共几个数字
第二行开始:每行描述一个数字(包括该数字前面的运算符)
x y z
x表示符号 123代表+*/ 然后x的正负代表数字正负
然后用y/z描述该数字大小
#include<bits/stdc++.h>//不能乘负数
using namespace std;
const int N=2021;
char s[3][N];
int len[3];
int top=0;
void exchange(int id){
top=0;
for(int i=0;i<len[id];i++){
char t=s[id][i];
if(t=='+'||t=='-'||t=='*'||t=='/'){
top++;
}
}
cout<<top+1<<endl;
int op=1;
int last_num=0;
for(int i=0;i<len[id];i++){
char t=s[id][i];
if(t=='+'||t=='-'){
cout<<op<<" "<<last_num<<" "<<1<<endl;//op的正负代表数字正负 123对应+*/
last_num=0;
if(t=='+')op=1;
else op=-1;
}
else if(t=='*'||t=='/'){
cout<<op<<" "<<last_num<<" "<<1<<endl;
last_num=0;
if(t=='*')op=2;
else op=3;
}
else if(t>='0'&&t<='9'){
last_num*=10;
last_num+=t-'0';
}
}
cout<<op<<" "<<last_num<<" "<<1<<endl;
}
int main(){
freopen("string.in","r",stdin);
freopen("1.2.in","w",stdout);
cin>>s[1];
len[1]=strlen(s[1]);
exchange(1);
cin>>s[2];
len[2]=strlen(s[2]);
exchange(2);
}
输入:
6 ∗ 6 ∗ 7 / 7 + 9 ∗ 5 ∗ 49 / 7 ∗ 4 − 140 − 6 6*6*7/7+9*5*49/7*4-140-6 6∗6∗7/7+9∗5∗49/7∗4−140−6
36 + 45 ∗ 28 − 146 36+45*28-146 36+45∗28−146
输出:
11 1 6 1 2 6 1 2 7 1 3 7 1 1 9 1 2 5 1 2 49 1 3 7 1 2 4 1 -1 140 1 -1 6 1 |
---|
4 1 36 1 1 45 1 2 28 1 -1 146 1 |
加减法
采用pair来存储每个数字
大体思路:把两个公式代表的数字算出来,判断是否相同
#include<bits/stdc++.h>
using namespace std;
int read(){
char s;
int x=0,f=1;
s=getchar();
while(s<'0'||s>'9'){
if(s=='-')f=-1;
s=getchar();
}
while(s>='0'&&s<='9'){
x*=10;
x+=s-'0';
s=getchar();
}
return x*f;
}
vector<pair<int,pair<int,int> > >v[3];//必须保证分子分母全是正整数
int len1,len2;
int gcd(int x,int y){
if(x<y)swap(x,y);
if(y==0)return x;
return gcd(y,x%y);
}
pair<int,pair<int,int> > pls(pair<int,pair<int,int> >a,pair<int,pair<int,int> >b){
int up_num,ud_num;
ud_num=a.second.second*b.second.second;
up_num=a.first*a.second.first*b.second.second+b.first*a.second.second*b.second.first;
int g=gcd(abs(ud_num),abs(up_num));
pair<int,pair<int,int> >r;
if(ud_num*up_num<0)r=make_pair(-1,make_pair(abs(up_num/g),abs(ud_num/g)));
else if(up_num==0)r=make_pair(1,make_pair(0,1));
else r=make_pair(1,make_pair(abs(up_num/g),abs(ud_num/g)));
return r;
}
double work(int id,int len){
int op=0;
pair<int,pair<int,int> >ans;
ans=make_pair(1,make_pair(0,1));
for(int i=0;i<len;i++){
pair<int,pair<int,int> >x;
x=v[id][i];
if(x.second.first==0)continue;
ans=pls(ans,x);
}
return (double)ans.first*ans.second.first/ans.second.second;
}
int main(){
freopen("1.1.in","r",stdin);
len1=read();
for(int i=1;i<=len1;i++){
int x,y,z;
x=read(),y=read(),z=read();
pair<int,pair<int,int> >t;
t=make_pair(x,make_pair(y,z));
v[1].push_back(t);
}
len2=read();
for(int i=1;i<=len2;i++){
int x,y,z;
x=read(),y=read(),z=read();
pair<int,pair<int,int> >t;
t=make_pair(x,make_pair(y,z));
v[2].push_back(t);
}
double ans1,ans2;
ans1=work(1,len1);
ans2=work(2,len2);
cout<<ans1<<endl;
cout<<ans2<<endl;
if(ans1==ans2)cout<<"一样"<<endl;
else cout<<"不一样"<<endl;
}
乘除法
由于乘除法有优先级,所以应该转为数字形式之后优先开始乘除法,然后把乘除法运输消除之后交给±法
每次遇到±:把之前的*/法全合并
比如 1 + 2 − 3 ∗ 2 ∗ 1 1+2-3*2*1 1+2−3∗2∗1
±号不管,遇见乘除之后,记录当前数字,然后把一连串的*/都进行压缩。
就变成了 1 + 2 − 6 1+2-6 1+2−6
#include<bits/stdc++.h>
using namespace std;
int read(){
char s;
int x=0,f=1;
s=getchar();
while(s<'0'||s>'9'){
if(s=='-')f=-1;
s=getchar();
}
while(s>='0'&&s<='9'){
x*=10;
x+=s-'0';
s=getchar();
}
return x*f;
}
vector<pair<int,pair<int,int> > >v[3];//必须保证分子分母全是正整数
int len1,len2;
int gcd(int x,int y){
if(x<y)swap(x,y);
if(y==0)return x;
return gcd(y,x%y);
}
pair<int,pair<int,int> > pls(pair<int,pair<int,int> >a,pair<int,pair<int,int> >b){
int up_num,ud_num;
ud_num=a.second.second*b.second.second;
up_num=a.first*a.second.first*b.second.second+b.first*a.second.second*b.second.first;
int g=gcd(abs(ud_num),abs(up_num));
pair<int,pair<int,int> >r;
if(ud_num*up_num<0)r=make_pair(-1,make_pair(abs(up_num/g),abs(ud_num/g)));
else if(up_num==0)r=make_pair(1,make_pair(0,1));
else r=make_pair(1,make_pair(abs(up_num/g),abs(ud_num/g)));
return r;
}
pair<int,pair<int,int> > multiplication(pair<int,pair<int,int> >a,pair<int,pair<int,int> >b){
//仅处理正整数部分的乘法即可 first已被处理
pair<int,pair<int,int> >ans;
ans.first=a.first;
pair<int,int> rec;
rec.first=a.second.first*b.second.first;
rec.second=a.second.second*b.second.second;
int g=gcd(rec.first,rec.second);
rec.first/=g;
rec.second/=g;
ans.second=rec;
return ans;
}
void work(int id,int len){
int ul=len;
for(int i=0;i<len;i++){
int use=abs(v[id][i].first);
if(use==2||use==3)ul--;
}
cout<<ul<<endl;
pair<int,pair<int,int> >rec;//记录当前*/压缩数字
rec.first=1;
rec.second=make_pair(1,1);
for(int i=0;i<len;i++){
pair<int,pair<int,int> >x;
x=v[id][i];
if(x.first==1||x.first==-1){
if(i!=0){
int use=rec.first>0?1:-1;
cout<<use<<" "<<rec.second.first<<" "<<rec.second.second<<endl;
}
rec=x;
continue;
}
if(abs(x.first)==2){//乘法
rec.first=rec.first*x.first>0?2:-2;
rec=multiplication(rec,x);
}
if(abs(x.first)==3){//除法
rec.first=(rec.first*x.first>0)?2:-2;
swap(x.second.first,x.second.second);
rec=multiplication(rec,x);
}
}
int use=rec.first>0?1:-1;
cout<<use<<" "<<rec.second.first<<" "<<rec.second.second<<endl;
}
int main(){
freopen("1.2.in","r",stdin);
freopen("1.1.in","w",stdout);
len1=read();
for(int i=1;i<=len1;i++){
int x,y,z;
x=read(),y=read(),z=read();
pair<int,pair<int,int> >t;
t=make_pair(x,make_pair(y,z));
v[1].push_back(t);
}
work(1,len1);
len2=read();
for(int i=1;i<=len2;i++){
int x,y,z;
x=read(),y=read(),z=read();
pair<int,pair<int,int> >t;
t=make_pair(x,make_pair(y,z));
v[2].push_back(t);
}
work(2,len2);
}