Description
给你一个用火柴棍摆成的个位数加减法算式,要你求出至少要移动多少根火柴棍才能使算式成立。等于和加号的那一横和减号不能移动,加号移掉一竖变成减号,减号移过来一竖变成加号。具体看图片的几个例子。
Input
多个样例(大约2000个),每个样例占一行,有a+b=c 或a-b=c其中0 <= a,b,c <= 9; 文件末尾表示输入结束;
Output
对于每个样例输出一个整数占一行,表示至少要移动多少根火柴棍才能使算式成立,若不能使算式成立,输出-1。
Sample Input
2+2=5
3-9=6
5-7=0
1-1=2
1-1=1
Sample Output
1
1
2
5
-1
HINT
Source
其实这道题并不算难,但是要思路想对,我们可以用二进制来表示每根火柴的位置,通过异或就能找出位置不同的火柴的根数,然后只要不相同的根数是偶数,就可以通过移动得到了
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <climits>
using namespace std;
#define LS 2*i
#define RS 2*i+1
#define UP(i,x,y) for(i=x;i<=y;i++)
#define DOWN(i,x,y) for(i=x;i>=y;i--)
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a)
#define gcd(a,b) __gcd(a,b)
#define LL long long
#define N 20005
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define EXP 1e-8
int num[10] = {6,2,5,5,4,5,6,3,7,6};
int bit[10] = {119,20,110,62,29,59,123,22,127,63};
int fun(int x)
{
int cnt = 0;
W(x)
{
if(x&1)
cnt++;
x/=2;
}
return cnt;
}
int main()
{
int i,j,k;
int a,b,c;
char x,y;
W(~scanf("%d%c%d%c%d",&a,&x,&b,&y,&c))
{
int cnt = 0,flag;
flag = (x=='+')?2:1;
cnt+=flag;
cnt+=num[a]+num[b]+num[c];
int s,sum,minn = INF;
UP(i,0,9)
{
UP(j,0,9)
{
UP(k,1,2)
{
if(k==1)
{
s = i-j;
if(s<0) continue;
sum=k;
}
else
{
s = i+j;
if(s>9) continue;
sum=k;
}
sum+=num[i]+num[j]+num[s];
if(sum!=cnt) continue;
//计算不同位置的火柴的根数,偶数时可行的
int p=(k==flag)?0:1;
p+=fun(bit[a]^bit[i])+fun(bit[b]^bit[j])+fun(bit[c]^bit[s]);
if(p%2==0)
{
p/=2;
minn = min(p,minn);
}
}
}
}
printf("%d\n",minn==INF?-1:minn);
}
return 0;
}