#next_permutation函数# CodeForces - 96B Lucky Numbers

CodeForces - 96B


Petya loves lucky numbers. Everybody knows that positive integers are lucky if their decimal representation doesn't contain digits other than 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are not.

Lucky number is super lucky if it's decimal representation contains equal amount of digits4 and 7. For example, numbers 47, 7744, 474477 are super lucky and 4, 744, 467 are not.

One day Petya came across a positive integer n. Help him to find the least super lucky number which is not less thann.

Input

The only line contains a positive integer n (1 ≤ n ≤ 109). This number doesn't have leading zeroes.

Output

Output the least super lucky number that is more than or equal to n.

Please, do not use the %lld specificator to read or write 64-bit integers in C++. It is preferred to use the cin, cout streams or the %I64d specificator.


题目大意:


寻找一个大于n的最小幸运数,幸运数:只由47组成,且4的数目和7的数目相等

扫描二维码关注公众号,回复: 939611 查看本文章



解题思路:


  • 首先判断数字长度len是否为奇数,如果是直接输出长度为len + 1 的最小幸运数
  • 如果不是,利用next_permutation(哈哈哈STL一下子就让他变成了水题)全排列函数寻找第一个大于等于输入数据的幸运数,将他输出
  • 如果未找到,输出长度为 len + 2的最小幸运数


解题关键:


next_permutation函数




next_permutation函数的用法:


      next_permutation( tem, tem + len ):重新排列范围内的元素(从第0个到第len个),使tem按照字典序转换为下一个较大的组合,若存在返回true,否则返回false

 


PS: 利用len & 1判断len是否为奇数,如果为真,那么len就是奇数



先上一份通俗易懂的代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <stack>
using namespace std;
const int MaxN = 1e8;

char digit[20], tem[20];

int main() {
	int n;
	scanf("%s", digit);
	int len = strlen(digit);
	if(len & 1) {    //为真说明 len 为奇数
		for(int i = 0; i <= len / 2; i++) printf("4");
		for(int i = 0; i <= len / 2; i++) printf("7");
		printf("\n");
		return 0;
	}
	for(int i = 0; i < len / 2; i++) tem[i] = '4';
	for(int i = len / 2; i < len; i++) tem[i] = '7';
	tem[len] = 0;   //这里的 0 实际是ASCII值
	//下面这个while循环是错的,因为在进入while循环时就已经将tem改为了下一个全排列
	/*while( next_permutation(tem, tem + len) ) {
		if( strcmp(digit, tem) <= 0) {
			printf("%s\n", tem);
			return 0;
		}
	}*/
	do {
		if( strcmp(digit, tem) <= 0) {
			printf("%s\n", tem);
			return 0;
		}
	} while( next_permutation(tem, tem + len) );

	for(int i = 0; i <= len / 2; i++) printf("4");
	for(int i = 0; i <= len / 2; i++) printf("7");
	printf("\n");
    return 0;
}

下面是一个CF大神的优美代码:

#include<iostream>
using namespace std;
typedef long long LL;

long long n, ans = 1LL << 60;

void solve(LL x, int y, int z) {  //通过x构造答案,y是4的个数,z是7的个数 
	if(x >= n && y == z) ans = min(ans, x);
	//答案ans满足要求:1.大于等于n  2.只存在7和4,且7的个数等于4的个数

	if(x > n * 100) return;      //答案肯定在 (n, n * 100) 之间
	solve(x * 10 + 4, y + 1, z); //当前答案 x 加一位数4 
	solve(x * 10 + 7, y, z + 1); //当前答案 x 加一位数7
}
int main() {
	cin >> n;
	solve(0, 0, 0);
	cout << ans << endl;
	return 0;
}


猜你喜欢

转载自blog.csdn.net/jasmineaha/article/details/79122235