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 ...
随机推荐
- 关于#define for if(false);else for
今日在看一个第三方代码时看到了#define for if(false);else for 这样的一种定义,不明白这样用法的目的,于是查了一下. 这是一个兼容vc6.0的用法,csdn上有这个问题的回 ...
- SQL 基础语法(一)
SQL 语法 数据库表 一个数据库通常包含一个或多个表.每个表由一个名字标识(例如"客户"或者"订单").表包含带有数据的记录(行). 下面的例子是一个名为 & ...
- C#笔记
关键字: 1.internal 被 internal 修饰的东西只能在本程序集(当前项目)内被使用. 注意事项: 1.解决c#代码引用c/c++代码出现的unsafe code错误警告提示 Unsaf ...
- sql server 取多个数字或者时间的最大值
SELECT MAX(b.a) from ( select distinct * from (values (1), (1), (1), (2), (5), (1), (6)) as Y(a) ) a ...
- 【hihocoder#1413】Rikka with String 后缀自动机 + 差分
搞了一上午+接近一下午这个题,然后被屠了个稀烂,默默仰慕一晚上学会SAM的以及半天4道SAM的hxy大爷. 题目链接:http://hihocoder.com/problemset/problem/1 ...
- mybatis源码分析:
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Helvetica Neue"; color: #e4af0a } p. ...
- linux下cetos7无线网络设置办法
首先检查是否安装了networkmanger wifi.RPM 检查方法,终端输入rpm一qa 如果不存在,利用rpm一ivh 文件名 进行安装,并且重启
- Redis五种数据结构简介
Redis五种结构 1.String 可以是字符串,整数或者浮点数,对整个字符串或者字符串中的一部分执行操作,对整个整数或者浮点执行自增(increment)或者自减(decrement)操作. 字符 ...
- Python批量扫描服务器指定端口状态
闲来无事用Python写了一个简陋的端口扫描脚本,其简单的逻辑如下: 1. python DetectHostPort.py iplist.txt(存放着需要扫描的IP地址列表的文本,每行一个地址) ...
- theano broadcasting
当我们使用函数对两个数组进行计算时,函数会对这两个数组的对应元素进行计算,因此它要求这两个数组有相同的大小(shape相同).如果两个数组的shape不同的话,会进行如下的广播(broadcastin ...