UVa1200 - A DP Problem 題解
阿新 • • 發佈:2021-06-19
題目大意
給定一個字串表示一個關於 \(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(""); } }