1. 408刷题
  2. C/C++

Permutation-问题

众所周知 algorithm 头文件 里有两个函数

next_permutation()
prev_permutation()

使用它们可以很方便的生成给定范围内的组合数。

首先尝试使用递归实现这个next_permutation()函数:

#include "cstdio"
int cnt = 0;
void per(int data[], int k)
{
	if(k >= 4)
	{
		printf("%d%d%d%d\n", data[0], data[1], data[2], data[3]);
		cnt++;
		return;
	}
	for(int i = k; i < 4; i++)
	{
		std::swap(data[i], data[k]);
		per(data, k + 1);
		std::swap(data[i], data[k]);
	}
}

int main()
{
	int data[] = {1, 2, 3, 4};
	per(data, 0);
	printf("Total:%d", cnt);
	return 0;
}

结果如下:

1234
1243
1324
1342
1432
1423
2134
2143
2314
2341
2431
2413
3214
3241
3124
3142
3412
3421
4231
4213
4321
4312
4132
4123
Total:24

 


实战一下:

// 问题描述
// 100 可以表示为带分数的形式:100 = 3 + 69258 / 714。
// 还可以表示为:100 = 82 + 3546 / 197。
// 注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0)。
// 类似这样的带分数,100 有 11 种表示法。
// 输入格式
// 从标准输入读入一个正整数N (N<1000*1000)
// 输出格式
// 程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数。
// 注意:不要求输出每个表示,只统计有多少表示法!
// 样例输入1
// 100
// 样例输出1
// 11
// 样例输入2
// 105
// 样例输出2
// 6

思路:

题目要求 1 ~ 9 数字全部出现;这时我们可以使用组合数来产生所有可能的组合

用加号和除号将组合数分成三个部分(如图所示)

对于某一个具体的组合数只要使用两个for循环来遍历这个组合数就可以得到这个组合数所有的可能

并和输入值res比较即可得出答案

#include "cstdio"
#include "algorithm"
using namespace std;
int num[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int cnt = 0;
int res = 0, left = 0, cent = 0, right = 0;
int to_int(int i, int j)//将组合数某个范围内的数字转INT
{
	int r = 0;
	int k = 1;
	for(; j >=i; j--)
	{
		r += num[j] * k;
		k *= 10;
	}
	return r;
}

void div()//分割函数
{
	for(int i = 0; i <= 6; i++)// 分割+
	{
		for(int j = i+1; j <= 7; j++)// 分割/
		{
			left = to_int(0, i);
			cent = to_int(i+1, j);
			right = to_int(j+1, 8);
			if(res * right == left * right + cent )//这里转化了一下表达式避免使用 / 所带来的精度问题
			{
				printf("%d = %d + %d / %d\n", res, left, cent, right);
				cnt++;
			}
		}
	}
	
}

int main()
{
	scanf("%d", &res);
	do{
	    div();
	}while(next_permutation(num, num + 9));
	printf("Total:%d", cnt);
	return 0;
}

输入:100

输出如下:

100 = 3 + 69258 / 714
100 = 81 + 5643 / 297
100 = 81 + 7524 / 396
100 = 82 + 3546 / 197
100 = 91 + 5742 / 638
100 = 91 + 5823 / 647
100 = 91 + 7524 / 836
100 = 94 + 1578 / 263
100 = 96 + 1428 / 357
100 = 96 + 1752 / 438
100 = 96 + 2148 / 537
Total:11