做洛谷p1618 三连击(升级版) 对暴力枚举有感

不多bb,线上链接:https://www.luogu.com.cn/problem/P1618

放题干:

开始分析:

刚看到题目,我们可能会有一个简单粗暴的想法:就是,我能不能从九个数里面拿三个数字给X,拿另外三个数给Y,然后最后三个数给Z,最后我们判断一下这个X:Y:Z 满 A:B:C。这个方法理论上是行得通的,我们需要借助一个 stl 函数 next_permutation(start,end) 头文件是algorithm 

这个函数的用处是随机排列一个数组,那我们可以用它随机排列1~9里的数字,前三个给X以此类推。

but.....我们今天讲的重点是暴力枚举

暴力枚举,就是通过枚举所有的情况来得到答案。最简单的做法是三个循环,x从123开始,到987结束,y从123开始,到987结束......

那么我们算一下 大概是循环 864*864*864*3*10 约为1e11

那么我们优雅地给它优化一下:

可以发现,其实不需要枚举 x,y,z;

只需要枚举一个数,然后通过比例来查找y,z是否存在就行了;

这样循环的次数大概是  (987-123)*3*10 == 1e5

大概思路:

枚举x,,123<=x<=987,然后查找 在A:B:C的比例下,y,z是否存在

如果存在,赋值y,z。

然后搞一个计数排序统计x,y,z各个位数的出现次数。

最后输出就行了。

上代码!!!!

typedef long long LL;
int flag[20];
void Flag(int x)
{
	int temp = x;
	while (temp)
	{
		flag[temp % 10] = 1;
		temp /= 10;
	}
}
bool check(int a, int b, int c)
{
	memset(flag, 0, sizeof(flag));
	Flag(a); Flag(b); Flag(c);
	for (int i = 1; i <= 9; i++)
		if (!flag[i])return false;
	return true;
}
int main()
{
	LL a, b, c, A, B, C,ans=0;
	cin >> A >> B >> C;//A<B<C
	if (A != 0) {
		for (a = 123; a <= 987; a++)
		{
			if ((a * B) % A or (a * C) % A) continue;
			b = (a * B) / A;
			c = (a * C) / A;
			if (b <= 987 and b >= 123 and c <= 987 and c >= 123)// b,c是三位数
			{
				if (check(a, b, c))
				{
					cout << a << ' ' << b << ' ' << c << endl;
					ans++;
				}
			}
		}
		if (ans == 0)cout << "No!!!";
	}
	else cout << "No!!!";
}

最后注意,A一定不能为0,所以我们还要分类讨论一下。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

louisdlee.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值