Google Code Jam 2016 Round 1B B
题意:给出两个数字位数相同,分别中间有若干位不知道,用问号表示。现在要求补全这两个数字,使得差值的绝对值最小,多解则取第一个数字的值最小的,再多解就取第二个数字最小的。
分析:
类似数位dp,但是很多状态可以直接得出最终解,个别状态需要状态转移。
我们从高位到低位依次确定两个数的每个位是几。一旦确定了两个数的一个位不一样,则可以立即将小的一方的后续问号全部写9,大的一方后续问号全部写0。这样才能让差值最小。
那我们观察每个位的时候要如何确定其值呢?分如下几种情况。
1.两个数的该位都是问号,那么分三种情况:
1.1 都标为0,看下一个位。
1.2&1.3 将一位标为1,另一个位标为0,并更新答案,终结状态。(这表示我们主动在高位制造了一个差值以便后面取得整体差值最小。例如:?0?,?9?,答案是100,099)
2.两个数的该位都不是问号,若相等,继续看下一位。若不等,则标出后面问号,更新答案,终结状态。
3.两个数的该位有一个是问号,那么这个这与第一种情况类似,分三种情况处理。
3.1 标为与该位相等,看下一个位。
3.2 标为该位减1,赋值后续问号,更新答案,终结状态。
3.3 标为该位加1,赋值后续问号,更新答案,终结状态。
就这么多情况。值得注意的是,虽然有些时候进行了状态转移(看下一个位)。但是并不需要搜索和回溯。因为每个状态的多个分支中,只有一个是状态转移,其他的都是最终态。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std; #define d(x) const int MAX_LEN = ; char st[][MAX_LEN];
char ans[][MAX_LEN];
char temp[][MAX_LEN];
long long diff;
int n; void input()
{
scanf("%s", st[]);
scanf("%s", st[]);
n = strlen(st[]);
} long long get_value(char st[])
{
long long ten = ;
long long ret = ;
for (int i = n - ; i >= ; i--)
{
ret += (st[i] - '') * ten;
ten *= ;
}
return ret;
} bool ok(long long temp_diff)
{
if (temp_diff > diff)
return false;
if (temp_diff < diff)
return true;
if (strcmp(ans[], temp[]) > )
return true;
if (strcmp(ans[], temp[]) < )
return false;
return strcmp(ans[], temp[]) > ; } void update()
{
long long a = get_value(temp[]);
long long b = get_value(temp[]);
long long temp_diff = abs(a - b);
if (ok(temp_diff))
{
diff = temp_diff;
strcpy(ans[], temp[]);
strcpy(ans[], temp[]);
}
} void make(int index, int a, int b)
{
if (a < || b < || a > || b > )
return; strcpy(temp[], st[]);
strcpy(temp[], st[]); temp[][index] = a + '';
temp[][index] = b + ''; int ch_a = '';
int ch_b = '';
if (a > b)
swap(ch_a, ch_b);
for (int i = index + ; i < n; i++)
{
if (temp[][i] == '?')
temp[][i] = ch_a;
if (temp[][i] == '?')
temp[][i] = ch_b;
}
d(printf("a=%d\n", a));
d(printf("b=%d\n", b));
d(puts(temp[]));
d(puts(temp[]));
update();
} void work()
{
diff = 1LL << ;
for (int i = ; st[][i]; i++)
{
if (st[][i] == st[][i] && st[][i] != '?')
{
continue;
}
if (st[][i] == st[][i] && st[][i] == '?')
{
make(i, , );
make(i, , );
st[][i] = st[][i] = '';
continue;
}
//reach here means st[0][i] != st[1][i]
if (st[][i] != '?' && st[][i] != '?')
{
make(i, st[][i] - '', st[][i] - '');
return;
}
//reach here means only one of them is ?.
if (st[][i] == '?')
{
make(i, st[][i] - '' + , st[][i] - '');
make(i, st[][i] - '' - , st[][i] - '');
st[][i] = st[][i];
}
if (st[][i] == '?')
{
make(i, st[][i] - '', st[][i] - '' + );
make(i, st[][i] - '', st[][i] - '' - );
st[][i] = st[][i];
} }
make(n - , st[][n - ] - '', st[][n - ] - '');
} int main()
{
int t;
scanf("%d", &t);
int case_num = ;
while (t--)
{
case_num++;
printf("Case #%d: ", case_num);
input();
work();
printf("%s %s\n", ans[], ans[]);
}
return ;
}
Google Code Jam 2016 Round 1B B的更多相关文章
- Google Code Jam 2016 Round 1B Problem C. Technobabble
题目链接:https://code.google.com/codejam/contest/11254486/dashboard#s=p2 大意是教授的学生每个人在纸条上写一个自己的topic,每个to ...
- Google Code Jam 2010 Round 1B Problem B. Picking Up Chicks
https://code.google.com/codejam/contest/635101/dashboard#s=p1 Problem A flock of chickens are runn ...
- Google Code Jam 2010 Round 1B Problem A. File Fix-it
https://code.google.com/codejam/contest/635101/dashboard#s=p0 Problem On Unix computers, data is s ...
- Google Code Jam 2016 Round 1C C
题意:三种物品分别有a b c个(a<=b<=c),现在每种物品各选一个进行组合.要求每种最和最多出现一次.且要求任意两个物品的组合在所有三个物品组合中的出现总次数不能超过n. 要求给出一 ...
- Google Code Jam 2014 Round 1B Problem B
二进制数位DP,涉及到数字的按位与操作. 查看官方解题报告 #include <cstdio> #include <cstdlib> #include <cstring& ...
- [C++]Store Credit——Google Code Jam Qualification Round Africa 2010
Google Code Jam Qualification Round Africa 2010 的第一题,很简单. Problem You receive a credit C at a local ...
- Google Code Jam 2010 Round 1C Problem A. Rope Intranet
Google Code Jam 2010 Round 1C Problem A. Rope Intranet https://code.google.com/codejam/contest/61910 ...
- [Google Code Jam (Qualification Round 2014) ] B. Cookie Clicker Alpha
Problem B. Cookie Clicker Alpha Introduction Cookie Clicker is a Javascript game by Orteil, where ...
- [Google Code Jam (Qualification Round 2014) ] A. Magic Trick
Problem A. Magic Trick Small input6 points You have solved this input set. Note: To advance to the ...
随机推荐
- python网络编程-OSI七层模型详解
OSI 七层模型通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯,因此其最主要的功能就是帮助不同类型的主机实现数据传输 . 完成中继功能的节点通常称为中继系统.在OSI七层模型中,处于 ...
- ROS中DDNS的使用
一.通过tool fetch更新ddns,关于此命令的使用,参考 tool fetch Scripts中添加脚本/tool fetch url="http://www.51kwl.com/? ...
- SVO原理解析
最近空闲时间在研究Semi-Direct Monocular Visual Odometry(SVO)[1,2],觉得它值得写一写.另外,SVO的运算量相对较小,我想在手机上尝试实现它. 关于SVO的 ...
- C#委托与事件
一.在控制台下使用委托和事件 我们都知道,C#中有"接口"这个概念,所谓的"接口"就是定义一套标准,然后由实现类来具体实现其中的方法,所以说"接口,是 ...
- OC与JavaScript的交互
stringByEvaluatingJavaScriptFromString的用法,它的功能非常的强大,用起来非常简单,通过它我们可以很方便的操作uiwebview中的页面元素. UIWebView是 ...
- jQuery—常用操作
一.jquery各版本变化 1.3:增加live(),为当前和将来增加的元素绑定事件 1.4:增加delegate().undelegate(),替代live(),可以遍历绑定 1.6:2个破坏性变更 ...
- strchr()函数 和 strrchr() 函数
strchr 定义于头文件 <string.h>char *strchr( const char *str, int ch );寻找ch(按照如同(char)ch的方式转换成char后)在 ...
- Asp.net C# 把 Datatable转换成JSON 字符串
First of all, we have to fetch the records from the database (MS Sqlserver) into the C# DataTable, o ...
- getchar fflush 的分析笔记
问题描述: 统计从键盘输入的若干个字符中有效字符的个数,以换行符作为输入结束.有效字符是指第一个空格符前面的字符,若输入字符中没有空格符,则有效字符为除了换行符之外的所有字符. 示例代码: #incl ...
- vi 的使用
Vi 分三种模式:一般模式,编辑模式,和命令模式 一般模式: 光标移动,搜索与替换,删除,复制,粘贴 编辑模式:插入或者替换文本 命令模式:读取.保存文件 一般模式 光标移动: h(左), j(下), ...