1. 程式人生 > 其它 >UVa1200 - A DP Problem 題解

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