2016年8月15日 星期一

北二區101-2小三數學(C++版)



參考程式碼:
#include <iostream>
using namespace std;
typedef long long LL;
const LL INF = 1e18;
int n,m , cnt;
string s;
LL a,b,c;

LL cal(LL x, LL y , char op) //依 op的符號算 x{op}y
{
switch(op)
{
case 0: // 0: +
 return x+y;
case 1: // 1: -
 return x-y;
case 2: // 2: *
 return x*y;
case 3: // 3: ÷//除數為0、無限大、不整除皆傳回 INF 代表答案不合
 if(y==0 || y==INF || x%y!=0 ) return INF; else return x/y;
}
}
char ops[]={'+','-','*','/'};
void cut2(int p) //分成兩個數字 a,b  呼叫 cal算出所有可能的值
{
int i;
for(a=0, i=0; i<p; ++i) a=a*10+s[i]-'0';
for(b=0, i=p; i<n; ++i) b=b*10+s[i]-'0';
for(int op=0; op<4; ++op)
{
LL r = cal(a,b,op);
if(r!=m) continue;
cout << a << ops[op] <<b << endl;
++cnt;  // 解的個數:本題好像都有解,故可以不用 cnt
}
}
LL cal3(int x, int y, int z, int op1, int op2)  //三個數 x{op1}y{op2}z
{
if( op1/2 < op2/2 ) // op1={0,1} && op2={2,3} , 則 先 * / 後 + -
  return cal( x,cal(y,z,op2) , op1) ;
else  return cal( cal(x,y,op1) ,z, op2) ;  //否則由左至右
}
void cut3(int p, int q) //分成三個數字 a,b,c  呼叫 cal3算出所有可能的值
{
int i,op1,op2;
for(a=0, i=0; i<p; ++i) a=a*10+s[i]-'0';
for(b=0, i=p; i<q; ++i) b=b*10+s[i]-'0';
for(c=0, i=q; i<n; ++i) c=c*10+s[i]-'0';
for( op1=0; op1<4; ++op1)
{
for(op2=0; op2<4; ++op2)
{
LL r = cal3(a,b,c,op1,op2);
if(r!=m) continue;
cout << a << ops[op1] <<b << ops[op2] <<c<< endl;
++cnt;  // 解的個數:本題好像都有解,故可以不用 cnt
} // op2
} // op1
}

int main(void) // 主程式
{
int i,j,t ;  //改成第一列有一數字t <10 ,有 t組資料,每組3列
cin >> t;
while( t--  )
  {
  cin >> n >> s >> m;
  cnt =0;  //解答數
LL k=0;
for(i=0; i<n; ++i) k=k*10+s[i]-'0';
if(k==m) { //只有一段{ 0 符號},就是等於答案
 cout << s << endl;
 return 0;
}
for(i=1; i<n; ++i)  // 分成兩部份{一個符號}
cut2(i);
if(n<3) continue;  // n < 3 只分成兩部份
for(i=1;i<n-1;++i)  // 分成三部份{二個符號}
 for(j=i+1; j<n; ++j)
   cut3(i,j);
if(cnt==0) cout << s<<','<<m <<"No Ans"<<endl; //無解:本題應該用不到
  }
return 0;
}
/* 範例
例一 : 12/3 = 4
3
123
4
例二 : 2+3*4 = 14
3
234
14
例三 : 240/15 = 16
5
24015
16
例四 8-6+2=4
3
862
4
例五 2+2=4 、 2*2=4
2
22
4
例六  1357-924*680=-626963
10 
1357924680 
-626963
例七 3*3-4=5 、 3/3+4=5
3
334
5
*/

0 意見:

張貼留言