http://codeforces.com/group/NVaJtLaLjS/contest/243021

You are helping an archaeologist decipher some runes. He knows that this ancient society used a
Base 10 system, and that they never start a number with a leading zero. He’s figured out most of
the digits as well as a few operators, but he needs your help to figure out the rest.
The professor will give you a simple math expression. He has converted all of the runes he knows
into digits. The only operators he knows are addition (+), subtraction (-), and multiplication (),
so those are the only ones that will appear. Each number will be in the range from −999, 999 to
999, 999, and will consist of only the digits ‘0’–‘9’, possibly a leading ‘-’, and a few ‘?’s. The ‘?’s
represent a digit rune that the professor doesn’t know (never an operator, an ‘=’, or a leading ‘-’).
All of the ‘?’s in an expression will represent the same digit (0–9), and it won’t be one of the other
given digits in the expression.
Given an expression, figure out the value of the rune represented by the question mark. If
more than one digit works, give the lowest one. If no digit works, well, that’s bad news for the
professor—it means that he’s got some of his runes wrong. Output −1 in that case.
Input
The sample data will start with the number of test cases T (1 ≤ T ≤ 100). Each test case will
consist of a single line, of the form:
[number][op][number]=[number]
Each [number] will consist of only the digits ‘0’-‘9’, with possibly a single leading minus ‘-’, and
possibly some ‘?’s. No number will begin with a leading ‘0’ unless it is 0, no number will begin
with -0, and no number will have more than 6 characters (digits or ?s). The [op] will separate the
first and second [number]s, and will be one of: +, - or . The = will always be present between the
second and third [number]s. There will be no spaces, tabs, or other characters. There is guaranteed
to be at least one ? in every equation.
Output
Output the lowest digit that will make the equation work when substituted for the ?s, or output
−1 if no digit will work. Output no extra spaces or blank lines.
Sample Input Sample Output
5
1+1=?
123
45?=5?088
-5?
-1=5?
19–45=5?
??*??=302?
2
6
0
-1
5

题意:把?处换成一个数字,若有多个符合,输出最小的;若没有符合或格式错误,输出-1。
注意题意:式子中已经有的数字不能填在?处。
看起来是一道简单的码农题,但还是有一些要注意的,思路不清晰很容易写错。
这道题一个很好的简化方法是定位两个符号,把字符串划分为3个数字的字符串(这步非常好),再借助sscanf函数,可以简化很多。

#include<bits/stdc++.h>
using namespace std;
#define ll long long

int T,n;
char s[100],t[100];
map<int,bool> mp;

bool check()
{
    int p;
    for(p=1;p<n;p++)
        if(t[p]=='+'||t[p]=='-'||t[p]=='*')break;
    int p2;
    for(p2=0;p2<n;p2++)if(t[p2]=='=')break;

    char c[100];int m=p;
    for(int i=0;i<m;i++)c[i]=t[i];
    if(m>1&&c[0]=='-'&&c[1]=='0')return false;
    if(m>1&&c[0]=='0'&&isdigit(c[1]))return false;
    m=p2-p-1;
    for(int i=0;i<m;i++)c[i]=t[p+1+i];
    if(m>1&&c[0]=='-'&&c[1]=='0')return false;
    if(m>1&&c[0]=='0'&&isdigit(c[1]))return false;
    m=n-p2-1;
    for(int i=0;i<m;i++)c[i]=t[p2+1+i];
    if(m>1&&c[0]=='-'&&c[1]=='0')return false;
    if(m>1&&c[0]=='0'&&isdigit(c[1]))return false;

    int r1,r2,r3;
    sscanf(t,"%d",&r1);
    sscanf(t+p+1,"%d",&r2);
    sscanf(t+p2+1,"%d",&r3);
    if(t[p]=='+')return r1+r2==r3;
    if(t[p]=='-')return r1-r2==r3;
    if(t[p]=='*')return r1*r2==r3;
}

int main()
{
    //freopen("input.in","r",stdin);
    cin>>T;
    while(T--)
    {
        mp.clear();
        bool ok=0;
        scanf("%s",s);
        n=strlen(s);
        for(int i=0;i<n;i++)if(isdigit(s[i]))mp[s[i]-'0']=1;
        for(int i=0;i<10;i++)
        {
            if(mp.count(i))continue;
            memcpy(t,s,sizeof(s));
            for(int j=0;j<n;j++)if(t[j]=='?')t[j]='0'+i;
            if(check())
            {
                printf("%d\n",i);
                ok=1;
                break;
            }
        }
        if(!ok)puts("-1");
    }
    return 0;
}