计蒜客:修道院的禁忌

【题目描述】

洋葱妹的公司最近与一个跨海相邻国家的修道院签订了业务,洋葱妹被派去与对方接触。

该国家的文化状态非常特别,身为君权神授的宗教国家,却对各种宗教都异常的包容,甚至明明是在同一个修道院里,却能有非常多种类的信仰共存。

洋葱妹想要打点一下关系,他听说修道院里有n个人,于是带了n个不同的礼物,但不同的宗教有着不同的禁忌,宗教A认为礼物A是一种无法饶恕的亵渎,礼物B对宗教B来说则完全不可想象。

洋葱妹在码头的集市找到了一个本地的牙人,打听清楚了各个宗教的禁忌,但即使这样,安排礼物也是一件费心费力的事,你能帮帮她吗?

【输入格式】

第一行两个数n,m,n为修道院人数,m为该注意的禁忌数(n≤11,m≤100)。                                     接下来m行,每行两个数a和b,表示宗教a不可以接受礼物b。

【输出格式】

输出总的方案数。

样例输入1
2 1
1 2
样例输出1
1
样例输入2
4 3
1 3
2 3
4 3
样例输出2
6

【C++代码】

        【解法1】全排列

#include <bits/stdc++.h>
using namespace std;
struct node{
    int a,b;
}jin[105];
int main(){
    int n,m;
    cin>>n>>m;
    int re[15];
    for(int i=1;i<=n;i++){
        re[i]=i;
    }
    for(int i=1;i<=m;i++){
        cin>>jin[i].a>>jin[i].b;
    }
    int ans=0;
    do{
        int flag=1;
        for(int i=1;i<=m;i++){
            if(re[jin[i].a]==jin[i].b){//去掉不可送的
                flag=0;
                break;
            }
        }
        ans+=flag;
    }while(next_permutation(re+1,re+1+n));
    cout<<ans;//输出
    return 0;
}

        【解法2】递归

#include<bits/stdc++.h>
using namespace std;
bool b[12][12];
int n,cnt=0;//不能定义成局部变量
bool vis[12];
long long a[100001];
void f(int x){
	if(x>n){
		cnt++;
		return;
	}
	for(int i=1;i<=n;i++){
		if(!vis[i] &&!b[x][i]){
			vis [i]=1;//两种情况:选/不选
			f(x+1);
			vis [i]=0;
		}
	}
}
int main(){
	int m,x,y;
	cin >> n >> m;
	while(m--){
		cin >> x>> y;
		b[x][y]=1;
	}
	f(1);
	cout << cnt;
	return 0;
}

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值