Codeforces Round #347 (Div. 2) B - Rebus
/* 期末考试后的第一次刷题,果然一段时间不刷就会退步的 = = = = 渣渣我 今天是第二天了终于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\n"; return 0; } else printf("Possible\n"); int k = 0 ; for(int i=0;i<l;i++) { if(str[i] == '?') cout<<ans[k++]; else cout<<str[i]; } return 0; }