您的位置:首页 > 其它

HDOJ 5676 ztr loves lucky numbers (贪心+数位DP)

2016-05-02 13:37 381 查看

题意

定义幸运数为只包含4和7并且4和7数量相等的数,给一个小于1e18的数,求大于这个数的第一个幸运数。

思路

思路一:实际上可以先打表dfs出所有的小于1e18的幸运数,然后每次输入n之后二分找就可以了,复杂度2^18,但是我想万一这个幸运数大于1e18不是不大好处理么,于是我就跑去贪心了(强行作死)。。。其实大于1e18只有一种情况,也就是大于777777777444444444LL(18位),这样直接输出44444444447777777777(20位)。

思路二:贪心加数位dp,也就是用字符串的形式构造出来这个答案,显然奇数是不可能4和7数量相等的,要在n的基础上加一位,如果大于n的位数的最大值时(即7…4)就要加两位,不然就是当前位数长度,在dfs的时候维护以下当前数字的高位是不是大于原数,然后判断当前位是加4还是7,因为有很多return所以复杂度我也不会算。。。但是比赛时10000组数据还是过了的,枚举时注意细节。

代码

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define LL long long
#define Lowbit(x) ((x)&(-x))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1|1
#define MP(a, b) make_pair(a, b)
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int maxn = 1e5 + 10;
const double eps = 1e-8;
const double PI = acos(-1.0);
typedef pair<int, int> pii;
string s;
char ans[10010];
int len;

bool dfs(int num4, int num7, bool big)
{
int cur = len - num4 - num7;
if (!num4 && !num7) return 1;
if (big)
{
if (num4) ans[cur] = '4', dfs(num4 - 1, num7, 1);
else ans[cur] = '7', dfs(num4, num7 - 1, 1);
return 1;
}
char snow = s[cur];
if (snow > '7')
return 0;
if (snow <= '7' && snow > '4')
{
if (num7)
{
if (dfs(num4, num7 - 1, !(snow == '7')))
{
ans[cur] = '7';
return 1;
}
}
else
return 0;
}
if (snow <= '4')
{
if (num4)
{
if (dfs(num4 - 1, num7, !(snow == '4')))
{
ans[cur] = '4';
return 1;
}
else
if (!num7)
return 0;
else
{
ans[cur] = '7';
dfs(num4, num7 - 1, 1);
return 1;
}
}
else
{
ans[cur] = '7';
dfs(num4, num7 - 1, 1);
return 1;
}
}
}

int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
scanf("%d", &T);
while (T--)
{
cin >> s;
len = s.size();
if (len & 1)
{
len++;
dfs(len / 2, len / 2, 1);
}
else
{
string t;
for (int i = 0; i < len / 2; i++)
t += '7';
for (int i = 0; i < len / 2; i++)
t += '4';
if (t < s)
{
len += 2;
dfs(len / 2, len / 2, 1);
}
else
{
dfs(len / 2, len / 2, 0);
}
}
ans[len] = '\0';
printf("%s\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: