竞赛水题:通关密码。

通关密码

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

bool 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值