NOIP2000普及组

【NOIP2000普及组T1】计算器的改良

NCL是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能。实验室将这个任务交给了一个刚进入的新手ZL先生。为了很好的完成这个任务,ZL先生首先研究了一些 
  一元一次方程的实例: 
  4+3x=8 
  6a-5+1=2-2a 
  -5+12Y=0 
  ZL先生被主管告之,在计算器上键入的一个一元一次方程中,只包含整数、小写字母及十、一、=这三个数学符号(当然,符号“一”既可作减号,也可作负号)。方程中并没有括号,也没有除号,方程中的字母表示未知数。 
【问题求解】 
  编写程序,解输入的一元一次方程,将解方程的结果(精确至小数点后三位)输出至屏幕。你可假设对键入的方程的正确性的判断是由另一个程序员在做,或者说可认为键入的一元一次方程均为合法的,且有唯一实数解。

输入文件仅一行,为一个字符串,长度不超过100。

输出文件仅一行,为方程的结果。

感觉这道题算是模拟题,有很多细节需要注意,同时也有技巧,把数字分为常数和系数处理,用两个数来模拟符号和等式左右边

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<set>
using namespace std;
const int maxn=1010;
const int INF=0x3fffffff;
string s;
//这道模拟题我只过了两组数据。。。。
//看了题解发现大家的思路都好清晰
//哭哭
/* 
int change(string x){
	int op=0;
	for(int i=0;i<x.length();i++) op=op*10+(x[i]-'0');
	return op;
}
int vis[maxn]={0};
*/ 
int l,r;//l表示系数,r表示常数
char x;//表示字母 
void solve(){
	char c;
	int f1=1,f2=1,temp=0;
	//f1表示是不是负数(负数-1,正数1),f2表示在等号左边还是右边,左边1,右边-1 
	//最后的结果(常数) :temp*(-f2)*f1,右边的负数时正的,左边的负数时负的,temp存储临时的数据 
	//系数:f1*f2,系数放在右边,所以右边是负就是负,左边正变负 
	while(scanf("%c",&c)!=EOF){  //根据输入一个个处理 
		if(c>='0'&&c<='9'){
			temp=temp*10;
			temp+=c-'0';
		}
		else{
			if(c>='a'&&c<='z'){
			if(temp==0) l+=f2*f1; //系数为1
			else l+=temp*f2*f1;
			x=c; 
		}
		else r+=temp*(-f2)*f1; //不是系数,就是常数,常数是(-f1)*f2
		temp=0; 
	}
	if(c=='+'){
		f1=1;continue;
	}
	else if(c=='-'){
		f1=-1;continue;  //表示系数的 
	}
	else if(c=='='){
		f2=-1;f1=1;  //都变,因为=右边第一个如果是正数是不会有符号的,所以要人为地把f1变为1 
		continue;
	}
}
 if(temp!=0) r+=temp*(-f2)*f1; //系数最后处理一下 
}


int main(){
	solve();
	printf("%c=%.3lf\n",x,1.0*r/l==0? abs(1.0*r/l):1.0*r/l);
	//因为会出现-0.0地情况,所以要排除这种情况,因为测评会过不了地 
	return 0;
	/* 
	cin>>s;
	char x;
	int j,temp,sumx=0,sumy=0;
	bool flag=0;
	string op;
	s=" "+s;
	for(int i=1;i<=s.length();i++){
		if(flag==0&&(s[i]>='a'&&s[i]<='z')){
			x=s[i];
			vis[i]=1;
			j=i;
			string stemp;
			while(s[--j]>='0'&&s[j]<='9'){
				stemp+=s[j];
				vis[j]=1;
			}
			temp=change(stemp);vis[j]=1; 
			if(s[j]=='-') temp=-temp;
			sumx+=temp;
		} 
		else if(s[i]=='=') flag=1;
		else if(flag==1&&(s[i]>='a'&&s[i]<='z')){
			j=i;
			vis[i]=1;
			string stemp;
			while(s[--j]>='0'&&s[j]<='9'){
				stemp+=s[j];
				vis[j]=1;
			}
			temp=change(stemp);vis[j]=1;
			if(s[j]=='+') temp=-temp;
			sumx+=temp; 
		}
	}
	flag=0;
	for(int i=1;i<=s.length();i++){
		if(s[i]=='=') flag=1;
		else if(s[i]>='0'&&s[i]<='9'&&vis[i]==0){
			j=i;
			string stemp;
			while(s[j]>='0'&&s[j]<='9'&&vis[j]==0) {
				stemp+=s[j];
				vis[j]=1;
				j++;
			}
			//cout<<"stre  "<<stemp<<endl;
			temp=change(stemp);
			//cout<<flag<<" "<<temp<<"  "<<s[i-1]<<endl;
			if(flag==0&&s[i-1]=='-') {
				temp=-temp;
			//	cout<<"zuo"<<temp<<endl;
			}
			else if(flag==1&&s[i-1]!='-') {
				temp=-temp;
				//cout<<"you"<<temp<<endl;
			}
			sumy+=temp;
		}
	}
	//for(int i=1;i<=s.length();i++) cout<<vis[i]<<" ";
	//cout<<endl;
	sumy=-sumy;
	//cout<<"zuo"<<temp<<endl;
	//cout<<sumx<<endl<<s<<endl<<-sumy<<endl;
	double res=double(sumy)/double(sumx);
	printf("%c=%.3lf\n",x,res);
	*/ 
return 0;
}

  

1215 -- 【NOIP2000普及组T2】税收与补贴问题

每样商品的价格越低,其销量就会相应增大。现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),并假设相邻价位间销量的变化是线性的且在价格高于给定的最高价位后,销量以某固定数值递减。(我们假设价格及销售量都是整数) 
  对于某些特殊商品,不可能完全由市场去调节其价格。这时候就需要政府以税收或补贴的方式来控制。(所谓税收或补贴就是对于每个产品收取或给予生产厂家固定金额的货币)
  问题求解:你是某家咨询公司的项目经理,现在你已经知道政府对某种商品的预期价格,以及在各种价位上的销售情况。要求你确定政府对此商品是应收税还是补贴的最少金额(也为整数),才能使商家在这样一种政府预期的价格上,获取相对其他价位上的最大总利润。
  总利润=单位商品利润*销量 
  单位商品利润=单位商品价格-单位商品成本(-税金 or +补贴)

输入的第一行为政府对某种商品的预期价
  第二行有两个整数,第一个整数为商品成本,第二个整数为以成本价销售时的销售量
  以下若干行每行都有两个整数,第一个为某价位时的单价,第二个为此时的销量,以一行-1,-1表示所有已知价位及对应的销量输入完毕
  输入的最后一行为一个单独的整数表示在已知的最高单价外每升高一块钱将减少的销量。

输出有两种情况:若在政府预期价上能得到最大总利润,则输出一个单独的整数,数的正负表示是补贴还是收税,数的大小表示补贴或收税的金额最小值。若有多解,取绝对值最小的输出。 
  如在政府预期价上不能得到最大总利润,则输出“NO SOLUTION” .

首先先把题目读懂(我好像完全不懂TAT

猜你喜欢

转载自www.cnblogs.com/shirlybaby/p/12732838.html