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, T. T 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
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;}
- Code Jam Round 1B 2016, Problem B. Close Match
- Code Jam 2010 Round 1B Problem B
- Code Jam 2010 Round 1A Problem B
- Code Jam 2010 Round 1B Problem A
- Code Jam 2010 Round 1B Problem C
- Google Code Jam Round 1A 2015 Problem B. Haircut
- Google Code Jam 2015 Round 1A: Problem B. Haircut
- Google code jam Round 1B
- Google Code Jam 2010 Qualification Round 2012 Problem B && C
- Code Jam 2017 Qualification Round Problem B. Tidy Numbers
- Google Code Jam 2017 Round 1B [B-large不会]
- Google Code jam 2013 Round 1B A题
- Google code jam Round1B Problem B
- Google code jam: Problem B. Reverse Words
- (code jam)Problem B. Reverse Words
- Google Code Jam-Problem B. Reverse Words
- (code jam)Problem B. Cookie Clicker Alpha
- Google Code Jam Qualification Round 2014 Problem B. Cookie Clicker Alpha 题解
- 机器学习(二) 如何做到机器学习竞赛Kaggle排名前2%
- 安卓Android扫描拍照身份证自动识别软件SDK
- 构造函数内的方法与构造函数prototype属性上方法的对比
- Leetcode 211. Add and Search Word
- Android-----装备选择
- Code Jam Round 1B 2016, Problem B. Close Match
- mr counter
- SQL多表查询之左右连接
- Jsp的四种作用域范围
- Leetcode 208. Implement Trie (Prefix Tree)
- IOS开发第三天-内存管理2
- NYOJ
- RAR 命令行语法
- 回文字符串