您的位置:首页 > 其它

ztr loves lucky numbers 傻逼的我来了个大模拟

2016-11-10 15:41 281 查看
http://acm.hdu.edu.cn/showproblem.php?pid=5676

这题的正解因该是dfs的,但是有18个位,然后我一算,全排列的话,有18!个啊,那不是很大?但是有很多是相同的,因为4477和第一个和第二个数字调转的结果是一样的。

先说说我模拟的方法。

真的很麻烦,不想看的,给几组数据就跑

7
0
8
4500
47
55
44447778
78
47777445

我是贪心模拟前n位,模拟的时候,如果这一位是3,如果我还有4,那么证明比后面的大了,然后后面的直接按4优先输出即可。

还有可能要加位的,就是78这样,要加位。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1e6 + 20;
LL ans[maxn];
int lenans;
void dfs(LL now, int num_four, int num_seven) {
if (num_four == 0 && num_seven == 0) {
ans[++lenans] = now;
return;
}
if (num_four == 0) {
dfs(now * 10 + 7, num_four, num_seven - 1);
} else if (num_seven == 0) {
dfs(now * 10 + 4, num_four - 1, num_seven);
} else {
dfs(now * 10 + 4, num_four - 1, num_seven);
dfs(now * 10 + 7, num_four, num_seven - 1);
}
}
void init() {
for (int i = 2; i <= 18; i += 2) {
dfs(0, i / 2, i / 2);
}
cout << lenans << endl;
}
void work() {
LL n;
scanf("%I64d", &n);
if (n > ans[lenans]) { //最大值777777777444444444。1e17内的最大值
printf("44444444447777777777\n");
} else {
//        LL tans = lower_bound(ans + 1, ans + 1 + lenans);
//        printf("%I64d\n", tans);
int begin = 1, end = lenans;
while (begin <= end) {
int mid = (begin + end) >> 1;
if (ans[mid] >= n) {
end = mid - 1;
} else begin = mid + 1;
}
printf("%I64d\n", ans[begin]);
}
}
int main() {
#ifdef local
freopen("data.txt","r",stdin);
#endif
init();
int t;
scanf("%d", &t);
while (t--) work();
return 0;
}


View Code
可以学习下DFS的做法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: