Code Jam Round 1B 2016, Problem B. Close Match

来源:互联网 发布:cn域名不备案能解析吗 编辑:程序博客网 时间:2024/06/05 22:46

https://code.google.com/codejam/contest/11254486/dashboard#s=p1


Problem

You are attending the most important game in sports history. The Oceania Coders are playing the Eurasia Jammers in the Centrifugal Bumble-Puppy world finals. Unfortunately, you were sleep deprived from all the anticipation, so you fell asleep during the game!

The scoreboard is currently displaying both scores, perhaps with one or more leading zeroes (because the scoreboard displays a fixed number of digits). While you were asleep, some of the lights on the scoreboard were damaged by strong ball hits, so one or more of the digits in one or both scores are not being displayed.

You think close games are more exciting, and you would like to imagine that the scores are as close as possible. Can you fill in all of the missing digits in a way that minimizes the absolute difference between the scores? If there is more than one way to attain the minimum absolute difference, choose the way that minimizes the Coders' score. If there is more than one way to attain the minimum absolute difference while also minimizing the Coders' score, choose the way that minimizes the Jammers' score.

Input

The first line of the input gives the number of test cases, TT cases follow. Each case consists of one line with two non-empty strings C and J of the same length, composed only of decimal digits and question marks, representing the score as you see it for the Coders and the Jammers, respectively. There will be at least one question mark in each test case.

Output

For each test case, output one line containing Case #x: c j, where x is the test case number (starting from 1), c is C with the question marks replaced by digits, and j is J with the question marks replaced by digits, such that the absolute difference between the integers represented by c and j is minimized. If there are multiple solutions with the same absolute difference, use the one in which c is minimized; if there are multiple solutions with the same absolute difference and the same value of c, use the one in which j is minimized.

Limits

1 ≤ T ≤ 200.
C and J have the same length.

Small dataset

1 ≤ the length of C and J ≤ 3.

Large dataset

1 ≤ the length of C and J ≤ 18.

Sample


Input 
 
Output 
 
41? 2??2? ??3? ??5 ?0
Case #1: 19 20Case #2: 023 023Case #3: 0 0Case #4: 05 00

In sample case #4, note that the answer cannot be 15 10; that minimizes the absolute difference, but does not minimize the Coders' score. Nor can the answer be 05 10; that minimizes the absolute difference and the Coders' score, but does not minimize the Jammers' score.



这道题并不是难题,但是还是颇有收获。

一开始,以为是贪心加枚举,特判各种情况即可得最后的答案,然而这正是出题者下的全套,这样做并不是做不出来而是case太多以至于崩溃。

其实看数据规模就可以大致估摸出来,这是一道搜索题

搜索的剪枝完全可以是平方算法 O(n^2), n = 18.


题意:给定两个位数相等的数,每个数的某些位缺失,用问好?填补。

现在问你,用0-9数字填上这些问好,使得两个数的差最小,如果多解的话,尽可能使第一个数最小,如果还有多解,就使得第二个数最小。


搜索思路:如果假定第一个数一定大于第二个数,那么填补这些问号就可以扫一遍完事。

枚举的时候,只有四种情况

??

?x

x?

xx

从高位向低位枚举(0->n),当枚举到第i位时,纪录前面是否出现第一个数一定大于(或者小于)第二个数, 这种情况处理起来比较简单。

如果前面是平局,那么,当前枚举完也有可能是 1⃣️平局,2⃣️大于,3⃣️小于

1⃣️平局: 也相对简单,两个数字ai bi保证相同, 如果都是问号,则 都是0

2⃣️大于:最优解一定是 |ai - bi|=1, 因为之前一直都是平局, 这样也好枚举。 如果都是问号则 1,0

3⃣️小于:同理


复杂度:最坏的情况,每一位都需要考虑 平局 大于 小于 三种情况,看似是 3^n 其实,如果前面不是平局,那么后面也不可能是平局,所以,最终的解,一定是:一直保持平局,然后转向 大于或者小于。这个分歧点只有n个,因此复杂度也是 O(n^2).


总结:看似,不仅要思考如何解题,更要学会判断题目类型,对症下药,切忌不要大炮打蚊子。


 


#include <cmath>#include <ctime>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <algorithm>#include <iostream>#include <queue>#include <map>using namespace std;#define FOR(i,a,b) for(int i=a;i<b;i++)#define FORE(i,a,b) for(int i=a;i<=b;i++)#define SCF(a) scanf("%d",&a)#define SCFU(a) scanf("%lld",&a)#define SCF2(a,b) scanf("%d%d",&a,&b)#define SCF3(a,b,c) scanf("%d%d%d",&a,&b,&c)#define min2(a,b) ((a)<(b))?(a):(b)#define max2(a,b) ((a)>(b))?(a):(b)#define MST(a,b) memset(a,b,sizeof(a))const int INF = 0x3FFFFFFF;const int MAXN = 2000+5;typedef long long int LL;//------------------------------------------------------------char num[2][25];int n;LL iCoders;LL iJammers;void print(LL x, int k){int q[25] = {0};FOR(i,0,k){q[i] = x%10;x /= 10;}FOR(i,0,k)printf("%d", q[k-1-i]);}bool better(LL c1, LL j1, LL c2, LL j2){if (  abs(j1-c1) < abs(c2-j2) ) return true;else if (  abs(j1-c1) == abs(c2-j2) ){if(c1 < c2) return true;else if((c1 == c2) && j1 <= j2) return true;}return false;}int flarge(int large,int u,int v){if(large!=0) return large;else if(u>v) return 1;else if(u<v) return -1;return 0;}void dfs(int i, int large, LL Coders, LL Jammers){//large={-1,0,1}if(i==n){if(iCoders<0 || better(Coders,Jammers,iCoders,iJammers) ){iCoders = Coders;iJammers = Jammers;}return;}int u,v;if(num[0][i]!='?' && num[1][i]!='?'){u = (num[0][i]-'0');v = (num[1][i]-'0');dfs(i+1,flarge(large,u,v),Coders * 10 + u,Jammers * 10 + v);}else if(large>0) { // num1>num2u = (num[0][i]=='?')?0:(num[0][i]-'0');v = (num[1][i]=='?')?9:(num[1][i]-'0');dfs(i+1,flarge(large,u,v),Coders * 10 + u,Jammers * 10 + v);}else if(large<0) { // num1<num2u = (num[0][i]=='?')?9:(num[0][i]-'0');v = (num[1][i]=='?')?0:(num[1][i]-'0');dfs(i+1,flarge(large,u,v),Coders * 10 + u,Jammers * 10 + v);}else{u = (num[0][i]=='?')?0:(num[0][i]-'0');v = (num[1][i]=='?')?0:(num[1][i]-'0');if( (num[0][i]=='?') && (num[1][i]=='?')){u = v = 0; dfs(i+1,flarge(large,u,v),Coders * 10 + u,Jammers * 10 + v);u = 0; v = 1; dfs(i+1,flarge(large,u,v),Coders * 10 + u,Jammers * 10 + v);u = 1; v = 0; dfs(i+1,flarge(large,u,v),Coders * 10 + u,Jammers * 10 + v);}else if( (num[0][i]!='?') && (num[1][i]=='?')){v = u; dfs(i+1,flarge(large,u,v),Coders * 10 + u,Jammers * 10 + v);v = u+1; if(v<=9) dfs(i+1,flarge(large,u,v),Coders * 10 + u,Jammers * 10 + v);v = u-1; if(v>=0) dfs(i+1,flarge(large,u,v),Coders * 10 + u,Jammers * 10 + v);}else if( (num[0][i]=='?') && (num[1][i]!='?')){u = v; dfs(i+1,flarge(large,u,v),Coders * 10 + u,Jammers * 10 + v);u = v+1; if(u<=9) dfs(i+1,flarge(large,u,v),Coders * 10 + u,Jammers * 10 + v);u = v-1; if(u>=0) dfs(i+1,flarge(large,u,v),Coders * 10 + u,Jammers * 10 + v);}}}int main(){freopen("data.in","r",stdin);freopen("data.out","w",stdout);int T;SCF(T);FOR(cse,0,T){scanf("%s%s", num[0],num[1]);iJammers = iCoders = -1;n = strlen(num[0]);dfs(0,0,0,0);printf("Case #%d: ",cse+1);print(iCoders,n);printf(" ");print(iJammers,n);printf("\n");}return 0;}




0 0
原创粉丝点击