UVa1200 - A DP Problem 题解

题目大意

给定一个字符串表示一个关于 \(x\) 的一元一次方程,求小于这个一元一次方程的解的最大整数。

多测,\(1\leq T\leq 10\)。所有系数都 \(a_i\in[0,1000]\) 且是整数。

下面给一组我手捏的样例。

Sample Input

5
0x=0
x+2=x+5
-114x=514
114x=514
98x+999+98x+999+98x+999=-1000-1000-1000-1000-1000x

Sample Output

IDENTITY
IMPOSSIBLE
-5
4
-6

分析

看起来就是一个大模拟,其实就是一个大模拟。

首先扫一遍整个字符串确定等号位置,然后分两边扫:等号左边作正号,等号右边移项过来作负号,然后分类讨论即可。

比较繁琐的是中间扫一遍的过程。具体看代码。

代码

#include<bits/stdc++.h>
#define HohleFeuerwerke using namespace std
#pragma GCC optimize(3,"Ofast","-funroll-loops","-fdelete-null-pointer-checks")
#pragma GCC target("ssse3","sse3","sse2","sse","avx2","avx")
#define int long long
HohleFeuerwerke;
inline int read(){
	int s=0,f=1;char c=getchar();
	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
	for(;isdigit(c);c=getchar()) s=s*10+c-'0';
	return s*f;
}
inline void write(int x){
	if(x<0) putchar('-'),x=-x;
	if(x>=10) write(x/10);
	putchar('0'+x%10);
}
int T;
string str;
signed main()
{
	T=read();
	while(T--){
		getline(cin,str); int n=str.size();
		int mark; //mark表示等号位置。
		for(int i=0;i<n;i++){
			if(str[i]=='='){
				mark=i; break;
			}
		}
		int a=0,b=0;//ax+b=0
		for(int i=0;i<mark;i++){
			if(str[i]=='x'){//系数为1时的讨论,前面不会有系数。
				int j;
				for(j=i;!isdigit(str[j])&&str[j]!='-'&&str[j]!='+'&&j>=0;j--);
				if(str[j]=='-') a-=1;
				else a+=1;
			}
			if(isdigit(str[i])){//系数不为1,注意要扫到这串数的末尾。
				int k,tmp=0;//k表示这串数末尾第一个位置,tmp表示这串数的值。
				for(k=i;isdigit(str[k]);k++);
				for(int l=i;l<k;l++) tmp=tmp*10+str[l]-'0';//这里是一个跟快读有点像的迭代方式。
				int l;
				for(l=i;l>=0&&str[l]!='-'&&str[l]!='+';l--);//这里的l表示这个数前一个符号位置,或者是第一项没有符号。
				if(str[l]=='-') tmp*=-1;//如果是负号直接乘-1,其余情况不用考虑
				for(l=k;str[l]!='x'&&str[l]!='+'&&str[l]!='-'&&str[l]!='=';l++);
				if(str[l]=='x') a+=tmp;//是未知数系数
				else b+=tmp;//是常数
				i=k;//直接跳
			}
		}
                //后面和上面的情况差不多,基本只需要多判断一个等号。
		for(int i=mark;i<n;i++){
			if(str[i]=='x'){
				int j;
				for(j=i;!isdigit(str[j])&&str[j]!='-'&&str[j]!='+'&&j>=0&&str[j]!='=';j--);
				if(str[j]=='-') a+=1;
				else a-=1;
			}
			if(isdigit(str[i])){
				int k,tmp=0;
				for(k=i;isdigit(str[k]);k++);
				for(int l=i;l<k;l++) tmp=tmp*10+str[l]-'0';
				int l;
				for(l=i;l>=0&&str[l]!='-'&&str[l]!='+'&&str[l]!='=';l--);
				if(str[l]=='-') tmp*=-1;
				for(l=k;str[l]!='x'&&str[l]!='+'&&str[l]!='-'&&str[l]!='=';l--);
				if(str[l]=='x') a-=tmp;
				else b-=tmp;
				i=k;
			}
		}
                //讨论
		if(a==0&&b==0) puts("IDENTITY");
		if(a==0&&b!=0) puts("IMPOSSIBLE");
		if(a!=0) write(floor((-b+0.)/a)),puts("");
	}
}
posted @ 2021-06-19 20:57  _HofFen  阅读(64)  评论(0编辑  收藏  举报