ACWING\1351. 密码锁

容斥原理

在这里插入图片描述

输入格式

第一行包含整数 N

第二行包含三个整数,表示约翰设置的密码组合。

第三行包含三个整数,表示制造商设置的密码组合。

输出格式

输出一个整数,表示可以打开锁的密码组合数量。

数据范围

1≤N≤100

输入样例:

50
1 2 3
5 6 7

输出样例:

249

题解

距离为2理解: 三个位置,每个位置都是距离为2以内,注意0与n相邻的循环(可以用mod进行处理)

  • 首先若n<=5,则密码锁中任何一个组合一定都与两个密码在距离为2之中,都可以打开,则必定只有nnn种方式
  • 首先将3个密码锁位的距离为2数字记录在集合 a b c。若两个密码的所有可打开组合不相交,则有250种(2*5*5*5);若相交,三个集合中就有数量少于10,最终组合数=250-a相交的部分*b相交的部分*c相交的部分
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <set>

using namespace std;

int main()
{
	int n;
	cin>>n;
	set<int> a,b,c;
	int x,y,z;
	/* 输入约翰密码和制造商密码并将每个密码位前后距离为2以内的五个数加入到集合 */
	for(int k = 0; k < 2; ++k){
		cin>>x>>y>>z;
		for(int i = -2; i < 3; ++i)
		{
			a.insert((x + n + i) % n); // 注意x+i为负数时候也mod正确
			b.insert((y + n + i) % n);
			c.insert((z + n + i) % n);
		}
	}
	
	/* 若n小于等于5,则密码锁任意一个组合都可以打开 */
	if(n<=5) cout<<n*n*n<<endl;
	else
	{
		/* 
		若两个密码的所有课打开组合不想交,则有250种(2*5*5*5)
		若相交,则在集合 a b c三个中就有数量少于10,
		最终组合数=250-a相交的部分*b相交的部分*c相交的部分
		*/
		cout<<250 - (10 - a.size()) * (10 - b.size()) * (10 - c.size());
	}	
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

AlwaysDayOne

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

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

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

打赏作者

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

抵扣说明:

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

余额充值