列表

详情


NC202493. 四个选项

描述

     众所周知,高考数学中有一个题目是给出12个单项选择,每一个选择的答案是 ABCD 中的一个。

     网上盛传答案存在某种规律,使得蒙对的可能性大大增加。于是今年老师想让你安排这12个题的答案。但是他有一些条件,首先四个选项的数量必须分别为 nanbncnd。其次有 m 个额外条件,分别给出两个数字 xy,代表第 x 个题和第 y 个题的答案相同。 现在你的老师想知道,有多少种可行的方案安排答案。

输入描述

第一行五个非负整数na,nb,nc,nd,m,保证na+nb+nc+nd=12,0≤m≤1000。

接下来m行每行两个整数x,y(1≤ x,y ≤12)代表第x个题和第y个题答案必须一样。

输出描述

仅一行一个整数,代表可行的方案数。

示例1

输入:

3 3 3 3 0

输出:

369600

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 4ms, 内存消耗: 496K, 提交时间: 2020-04-11 13:45:11

#include<bits/stdc++.h>
using namespace std;
int c[10];
int xx;
int yy;
int a[10],ans,b[20],m;
bool e[20][20],ok;
void dfs(int now) {
	if(now>12) {
		ans++;
		return ;
	}
	for(int i=1;i<=4;i++) {
		if(a[i]<c[i]) {
			ok=1;
			for(int j=1;j<=now-1;j++) {
				if(e[j][now]&&b[j]!=i) {
					ok=0;
					break;
				}
			}
			if(!ok) continue;
			a[i]++;
			b[now]=i;
			dfs(now+1);
			a[i]--;
		}
}
}
int main() {
	for(int i=1;i<=4;i++) {
		cin>>c[i];
	}
	cin>>m;
	while(m--) {
		cin>>xx>>yy;
		e[xx][yy]=e[yy][xx]=1;
	}
	dfs(1);
	cout<<ans<<endl;
	return 0;
} 

C++14(g++5.4) 解法, 执行用时: 3ms, 内存消耗: 380K, 提交时间: 2020-04-10 19:20:31

#include<stdio.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
int c[5],xx,yy,a[5],ans,b[20],m;
bool e[20][20],ok;
void dfs(int now){
	if (now>12){
		ans++;
		return;
	}
	fo(i,1,4)if (a[i]<c[i]){
		ok=1;
		fo(j,1,now-1) if (e[j][now]&&b[j]!=i){
			ok=0;
			break;
		}
		if (!ok) continue;
		a[i]++;
		b[now]=i;
		dfs(now+1);
		a[i]--;
	}
}
int main(){
	fo(i,1,4) scanf("%d",&c[i]);
	scanf("%d",&m);
	while (m--){
		scanf("%d%d",&xx,&yy);
		e[xx][yy]=e[yy][xx]=1;
	}
	dfs(1);
	printf("%d\n",ans);
	return 0;
}

上一题