竞赛水题:通关密码。

来源:互联网 发布:网店美工课教案 编辑:程序博客网 时间:2024/05/17 22:09

通关密码

 题目描述:
  周末,小雪到游乐园去游玩,在智力大冒险的游戏中,他一路过关斩将,现在只剩下一个问题,只要他能回答出来,那么智力宝库的大门就会打开,小雪就能得到过关的奖品。宝库的大门上有形如A □ B □ C的算术表达式,其中A、B、C是任意整数(-1025<A,B,C<1025),符号□中要填放加或减运算符。宝库的守门人会按顺序任意给出A、B、C三个数,小雪要做的就是想想如何向符号□中填放加、减号,使运算结果为4。如能得到4,那么告诉守门人计算式,他就会为你打开宝库大门。如不能得到4,就告诉守门人“no”,那么他就会重新给你一组数据。你能编程帮助小雪解决这个难题吗?

程序输入说明

一共有三行。每行包含一个整数,按顺序分别表示A,B,C。

程序输入样例

422

程序输出样例

4+2-2
[EOF]

提示

A,B,C可以为负数,假设A=4,B=2,C=-2,这时表达式不允许为:4+2+(-2),正确形式应为:4+2-2。
测试数据中不存在多解的情况 

多说无益,直接上代码。

#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#define MAX_L 108using namespace std;int a[MAX_L+8],b[MAX_L+8],c[MAX_L+8],tmp[MAX_L+8];//!定义四个数组 数组的长度均为116。MAX_L值已经定义为108。int len_a,len_b,len_c,len_tmp;//!定义四个变量,a,b,c,tmpint res1[MAX_L+8],len_1;int res2[MAX_L+8],len_2;int res3[MAX_L+8],len_3;int res4[MAX_L+8],len_4;//!分别定义四个数组,数组长度为len_1 len_2 len_3 len_4bool fa=0,fb=0,fc=0;//!定义四个布尔变量,用来记录三个数字的正负char s[MAX_L+8];//!定义一个长度为116的字符数组S 用来读入输入的字符串,即题目中的数字//!(字符串模拟)输入数,判断正负并首尾调换,并转换为整型数组储存。void read(int num[],int &len,bool &f){  scanf("%s",&s);//!输入字符串  int l=strlen(s);//!测量字符串长度  len=0;  if (s[0]=='-') f=1;//!如果输入的为负值,布尔变量的值变为1:  for (int i=0;i<l;++i) if ('0'<=s[i] && s[i]<='9') num[len++]=s[i]-'0';//!转化为int类型的数组  for (int i=0;i<len/2;++i) swap(num[i],num[len-i-1]);//!首尾调换}//!大数加法函数void add(int res[],int &n,int a[],const int &la,int b[],const int &lb){  int len=max(la,lb);//!找出两个长度中,最大的那一个  for (int i=la;i<len;++i) a[i]=0;//!多出的长度数字改为0  for (int i=lb;i<len;++i) b[i]=0;//!多出的长度数字改为0  for (int i=0;i<=len;++i) res[i]=0;//!0-len长度全部重置为0;  for (int i=0;i<len;++i) {  res[i]+=a[i]+b[i];  res[i+1]+=res[i]/10;  res[i]%=10;}  n=len;  while (res[n]>0) res[n+1]=res[n]/10,res[n]%=10,++n;//!最后一位进位,如果大于10,长度加一  //printf("%d %d\n",n,res[0]);}//!判断两个式子能否相减的函数。bool cmp(int a[],int &la,int b[],int &lb) {  if (la>lb) return 1;  if (la<lb) return 0;  for (int i=la-1;i>=0;--i)//!C++中写成--i可以减轻机器的负担。  {    if (a[i]>b[i]) return 1;//!返回1为真,返回0为假。    if (a[i]<b[i]) return 0;  }  return 1;}//!大数减法函数void odd(int res[],int &n,int a[],const int &la,int b[],const int &lb) {  int len=max(la,lb);//!取最大的长度  for (int i=la;i<len;++i) a[i]=0;//!多出的长度空间改为0  for (int i=lb;i<len;++i) b[i]=0;//!多出的长度空间改为0  for (int i=0;i<=len;++i) res[i]=0;  for (int i=0;i<len;++i) {    res[i]+=a[i]-b[i];    if (res[i]<0) res[i+1]-=1,res[i]+=10;//!如果相反,退位(即i+1),加10;  }  n=len;  while (n && res[n-1]==0) --n;//!总长度-1,可以减多次,长度不能为0,最后结果若刚好为0,则输出即是0;}//!负责输出的函数//!逆序输出void print(int num[],int n){  for (int i=n-1;i>=0;--i) printf("%d",num[i]);}//!下面的注释代码是大佬用来检测自己所写的代码是否正确的。int main() {  read(a,len_a,fa);  read(b,len_b,fb);  read(c,len_c,fc);//!读入三个数字串 存放到三个数组 a[] b[] c[]中/*for (int i=0;i<len_a;++i) printf("%d",a[i]);putchar('\n');for (int i=0;i<len_b;++i) printf("%d",b[i]);putchar('\n');for (int i=0;i<len_c;++i) printf("%d",c[i]);putchar('\n');*/  //!odd大数减法 cmp比较函数 add大数加法  //!如果fa=0,运行该if语句。即数字a>=0时候运行。  if (!fa) {  add(tmp,len_tmp,a,len_a,b,len_b);//!a,b相加 a+b  //for (int i=len_tmp-1;i>=0;--i) printf("%d",tmp[i]);  if (cmp(tmp,len_tmp,c,len_c))//!判断能否相减大于0,可以则执行  {    odd(res1,len_1,tmp,len_tmp,c,len_c);//!a+b-c//for (int i=len_1-1;i>=0;--i) printf("%d",res1[i]);putchar('\n');    //!位数为1 值为4输出if (len_1==1 && res1[0]==4) { print(a,len_a);putchar('+');print(b,len_b);putchar('-');print(c,len_c);return 0; }  }  add(res2,len_2,tmp,len_tmp,c,len_c); //!不能相减,则相加。a+b+c;  //!位数为1 值为4输出  if (len_2==1 && res2[0]==4) { print(a,len_a);putchar('+');print(b,len_b);putchar('+');print(c,len_c);return 0; }  add(tmp,len_tmp,a,len_a,c,len_c);//!a+c  //!判断a+c能否减b 大于0 可以则执行  if (cmp(tmp,len_tmp,b,len_b)) {  odd(res3,len_3,tmp,len_tmp,b,len_b);//!a+c-b  //!位数为1 值为4输出  if (len_3==1 && res3[0]==4) { print(a,len_a);putchar('-');print(b,len_b);putchar('+');print(c,len_c);return 0; }  }  //!a能否减b 大于0 可以执行  if (cmp(a,len_a,b,len_b)) {  odd(tmp,len_tmp,a,len_a,b,len_b);//!a-b  //!判断能否a-b-c 大于0 则执行  if (cmp(tmp,len_tmp,c,len_c)) {    odd(res4,len_4,tmp,len_tmp,c,len_c);//!a-b-c    //!位数为1 值为4输出    if (len_4==1 && res4[0]==4) { print(a,len_a);putchar('-');print(b,len_b);putchar('-');print(c,len_c);return 0; }    }  }  }  //!上一块代码判断了 a+b+c a+c-b a+b-c a-b-c (a>=0)的时候的所有情况  b c 取绝对值是没有影响的  //!若a小于0   else {  add(tmp,len_tmp,a,len_a,b,len_b);//!a+b  //!判断c能减a+b吗,可以就执行。  if (cmp(c,len_c,tmp,len_tmp)) {    odd(res1,len_1,c,len_c,tmp,len_tmp);//!c-(a+b)    //!位数为1 值为4输出    if (len_1==1 && res1[0]==4) { putchar('-');print(a,len_a);putchar('-');print(b,len_b);putchar('+');print(c,len_c);return 0; }    }    add(tmp,len_tmp,a,len_a,c,len_c);//!a+c    //!b能减(a+c)吗,可以就执行  if (cmp(b,len_b,tmp,len_tmp)) {    odd(res2,len_2,b,len_b,tmp,len_tmp);//!b-(a+c)    //!位数为1 值为4输出    if (len_2==1 && res2[0]==4) { putchar('-');print(a,len_a);putchar('+');print(b,len_b);putchar('-');print(c,len_c);return 0; }    }    add(tmp,len_tmp,b,len_b,c,len_c);//!b+c;    //!b+c能-a吗 可以就减  if (cmp(tmp,len_tmp,a,len_a)) {    odd(res3,len_3,tmp,len_tmp,a,len_a);//!(b+c)-a;    //!位数为1 值为4输出    if (len_3==1 && res3[0]==4) { putchar('-');print(a,len_a);putchar('+');print(b,len_b);putchar('+');print(c,len_c);return 0; }    }  }  //!这一块代码判断了a-b+c  a+b-c a+b+c (a<0) 无需考虑 a-b-c因为必小于0   bc取绝对值是没有影响的  printf("no\n");  return 0;}