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("");
}
}