Codeforces Round #347 (Div. 2) B

/* 
期末考试后的第一次刷题,果然一段时间不刷就会退步的 = = 

= = 渣渣我 今天是第二天了终于AC 各种查漏补缺(笑cry) 
以后考虑问题还是要全面仔细 = =

题意:补全算式 使之等于最后的数 n。 
 
大概思路就是,因为等式最后要等于 n ,而 n 只有从带加号的数里获得 (多出来的数有减号可以减去)。。
然后就让所有带加号的数的总和等于 (X + n ) ,带减号的数的总和等于 X ,这样整个式子就等于 n 了 = = 
先统计出加号和减号的个数分为记为 a 和 s 。 

(X + n )的值:
在加减号都有的情况下 (X + n )最少可以是 (n + s),即 n 加上减号的数量 ,这样减号那边都填1 
但如果只有加号 那么为 a+1 (最前面是个正数但是统计加号的时候没有统计到所以加1) 
只有减号肯定是不成立的。
加号是给定的又不能填 0 所以取两者中较大的 。

 
*/

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
int main()
{
    char str[2000],fg[110];
    int a = 0, s = 0; 
    memset(str,0,sizeof(str));
    gets(str);
    int l = strlen(str), n=0, j=1 ;
    for(int i=l-1; i>=0; i--)
    {
        if(str[i] == ' ') break;
        n = (str[i]-48)*j + n;
        j*=10;
    }
    int c = 1; fg[0] = '+';
    for(int i=0;i<l;i++)
    {
        if(str[i] == '+')
        {
            fg[c++] = str[i]; a++;
        }
        else if(str[i] == '-')
        {
            fg[c++] = str[i]; s++;
        }
    }
    int sum = n,y = 0;
    int ans[110];
    memset(ans,0,sizeof(ans)); ans[0] = sum;

    int f = 1;
    if( a==0 && s!=0) f = 0;
    
        int mx = max((sum+s),a+1);
        int x = mx/(a?a+1:1);
        for(int i=0;i<c;i++)        
            if(fg[i] == '+')  ans[i] = x;
        y = mx - (a+1)*x;
        if(y>0) 
        {
            for(int i=0;i<c;i++)    
            {
                if(y<=0) break;
                if(fg[i] == '+')
                {
                    ans[i] ++; y--;
                }  
            }                    
        }
        x = (mx-n)/(s?s:1); 
        
        if(x>s*sum) f = 0; // 每个减号最多减去 n ,如果减不完式子不能成立 
        
        for(int i=0;i<c;i++)        
            if(fg[i] == '-')  ans[i] = x;
        y = mx-n-s*x ;
        if(y > 0) 
        {
            for(int i=0;i<c;i++)    
            {
                if(y<=0) break;
                if(fg[i] == '-')
                {
                    ans[i] ++; y--;
                }  
            }                    
        }
    
    for(int i=0;i<c;i++)
        if(ans[i]>n || ans[i]<=0) f =0;
                
    if( !f ) 
    {
        cout<<"Impossible
"; return 0; 
    }
    else printf("Possible
");
    int k = 0 ;
    for(int i=0;i<l;i++)
    {
        if(str[i] == '?') cout<<ans[k++];
        else cout<<str[i]; 
    }           
        
    return 0;
}
原文地址:https://www.cnblogs.com/ember/p/5681354.html