输入数据有n+1行: 第一行为工程师人数n(1 ≤ n ≤ 6) 接下来的n行,每行一个字符串表示第i(1 ≤ i ≤ n)个人能够胜任的工作(字符串不一定等长的)
输出一个整数,表示有多少种不同的工作安排方案
6 012345 012345 012345 012345 012345 012345
720
//利用回溯法求解.//题意有两个地方没说清楚:1、一个人只能做一项工程,而不能分饰两角;// 2、有几个工程师,每个工程师有一个工作即满足题意,不用6项工作全部都要有人做。//前一个人选了哪项工作,直接影响后一个人的选择余地。//所以需要用一个set记录在当前这个人选择之前,前面那些人已经选了的工作,进而他只能选除set中已有剩下的工作。//当考察完最后一个人,情况数+1(递归出口),证明是满足题意的方案。下面是代码import java.util.HashSet; import java.util.Scanner; //网易:工程师与项目的匹配 public class Wangyi_WorkAndWorker { private static int cases = 0; public static void main(String[] args) { //读取输入 Scanner in = new Scanner(System.in); int n = in.nextInt(); String[] ables = new String[n]; for(int i = 0; i < n; i++) ables[i] = in.next(); //计算 backtracing(ables, 0, new HashSet<Integer>()); System.out.println(cases); in.close(); } public static void backtracing(String[] ables, int index, HashSet<Integer> set){ if(index >= ables.length){ cases++; return; } String able = ables[index]; for(int i = 0; i < able.length(); i++){ int work = able.charAt(i) - '0'; if(!set.contains(work)) { set.add(work); backtracing(ables, index + 1, set); set.remove(work); } } } }
package go.jacob.day914;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
/**
* [编程题]工作安排
*
* @author Jacob
* 利用回溯法求解
*
* 需要说明的是:
* 不必每一项工作都有人做,只要每个人都分配到工作即可
*
*/
public class Demo1 {
public static int count = 0;
public static Set<Integer> set;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String[] strs = new String[n];
set = new HashSet<Integer>();
for (int i = 0; i < n; i++) {
strs[i] = sc.next();
}
for (int i = 0; i < 6; i++) {
set.add(i);
}
solve(strs, 0);
System.out.println(count);
sc.close();
}
private static void solve(String[] strs, int k) {
if (k == strs.length) {
count++;
return;
}
for (char c : strs[k].toCharArray()) {
if (set.contains(c - '0')) {
set.remove(c - '0');
solve(strs, k + 1);
set.add(c - '0');
}
}
}
}
n=int(raw_input()) joblist=[] for i in range(n): joblist.append(raw_input().strip()) def work_assign(i,joblist,res): result=0 for k in joblist[i]: if k not in res: if i==n-1: result+=1 else: result+=work_assign(i+1,joblist,res+[k]) return result print(work_assign(0,joblist,[])) 跟背包放法问题相似
import java.util.Scanner;
public class Main {
static int count = 0;
static int n = 0;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
count = 0;
n = in.nextInt();
String[] ability = new String[n];
for (int i = 0; i < n; i++) {
ability[i] = in.next();
}
generate(ability,0, 0);
System.out.println(count);
}
private static void generate(String[] ability,int peopleNumber, int current) {
String s=ability[peopleNumber];
if (peopleNumber == n-1) {
for(int i=0;i<s.length();i++){
int job=s.charAt(i)-'0';
if ((current&(1<<job))==0){
count++;
}
}
} else {
for(int i=0;i<s.length();i++){
int job=s.charAt(i)-'0';
if ((current&(1<<job))==0){
generate(ability,peopleNumber+1,current|(1<<job));
}
}
}
}
}
/*
这道题目题意有点模糊
其实意思是:
1、所有工程师都必须有事可做,且只能做一件事情。
2、不必所有事都要做。
下面的代码就是实现上述功能
*/
#include <iostream>
using namespace std;
#include<string.h>
#define N 6
int sum = 0;
int b[N] = {0}; //记录工作是否被做过
int main(int argc, char *argv[])
{
void fun(string a[], int m, int k);
string a[N];
int k;
cin>>k;
for(int i = 0; i < k; i++)
cin>>a[i];
fun(a, 0, k);
cout<<sum<<endl;
return 0;
}
//回溯法求解
void fun(string a[], int m, int k)
{
if (m == k) {
sum++;
}
else {
for (int j = 0; j < a[m].size(); j++) {
int temp = (int)(a[m][j] - '0');
if (b[temp] == 0) {
b[temp] = 1;
fun(a, m + 1, k);
b[temp] = 0;
}
}
}
}
#include <iostream>
#include <vector>
#include<set>
#include<string>
using namespace std;
void backtracing(string str[], int index,int n, set<int> sev);
int cases = 0;
int main()
{
int n = 0;
cin >> n;
string str[6];
int index = 0;
set<int> sev ;
for (int i = 0; i < n; ++i)
{
cin>>str[i];
}
backtracing(str, 0, n, sev);
cout << cases << endl;
}
void backtracing(string str[], int index,int n, set<int> sev)
{
if (index == n)
{
++cases;
return;
}
string str0 = str[index];
for (int i = 0; i < str0.length(); i++){
int work = str0[i] - '0';
if (sev.find(work)==sev.end()) {
sev.insert(work);
backtracing(str, index + 1,n, sev);
sev.erase(work);
}
}
} n = int(input()) canDo = [input() for _ in range(n)] done = [False] * 6 def solve(i): if i == n: return 1 res = 0 for k in range(6): if not done[k] and (str(k) in canDo[i]): done[k] = True res += solve(i+1) done[k] = False return res print(solve(0))
#include <iostream>
#include <vector>
using namespace std;
int queenProblem(const vector<vector<bool>> &a, vector<bool> &mask, int id)
{
int i, sum = 0;
for(i = 0; i < 6; i++)
if (a[id][i] && mask[i])
{
if (id == 0)
sum += 1;
else
{
mask[i] = false;
sum += queenProblem(a, mask, id - 1);
mask[i] = true;
}
}
return sum;
}
int main()
{
int n, i, j;
cin >> n;
vector<vector<bool>> a(n, vector<bool>(6, false));
string str;
for (i = 0; i < n; i++)
{
cin >> str;
for (j = 0; j < str.length(); j++)
a[i][str[j] - '0'] = true;
}
vector<bool> mask(6, true);
cout << queenProblem(a, mask, n - 1) << endl;;
return 0;
} 类似于八皇后问题,准确的说更像是n堡垒问题?
#include <bits/stdc++.h>
using namespace std;
int n;
int ans;
vector<vector<int>> able(10, vector<int>(0));
int work[10];
void init()
{
for (int i = 0; i < 10; i++)
able[i].clear();
}
void dfs(int i)
{
if (i == n + 1)
{
ans++;
return;
}
else
{
int len = able[i].size();
for (int j = 0; j < len; j++)
{
int v = able[i][j];
if (!work[v])
{
work[v] = 1;
dfs(i + 1);
work[v] = 0;
}
}
}
}
int main()
{
while (cin >> n)
{
ans = 0;
init();
memset(work, sizeof(work), 0);
string s;
for (int i = 1; i <= n; i++)
{
cin >> s;
for (int j = 0; j < s.size(); j++)
able[i].push_back(s[j] - '0');
}
dfs(1);
cout << ans << endl;
}
system("pause");
return 0;
} import sys class Solution: def get_work_assignment(self, arr): count = [0] for i in arr[0]: self.process(arr, i, 1, count) print(count[0]) def process(self, arr, path, level, count): if level == len(arr): count[0] += 1 return for i in arr[level]: if i not in path: self.process(arr, path+i, level+1, count) if __name__ == '__main__': n = int(sys.stdin.readline()) args = list() for _ in range(n): args.append(sys.stdin.readline().strip()) solution = Solution() solution.get_work_assignment(args)
import java.util.Scanner;
/*
* 非常典型的dfs解题方法,然后使用visited防止元素重复访问
* */
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
n = scanner.nextInt();
String[] strs = new String[n];
for (int i = 0; i < n; i++) {
strs[i] = scanner.next();
}
// 有六项任务
boolean[] used = new boolean[6];
dfs(used, strs, 0);
System.out.println(count);
}
}
private static int count = 0;
private static int n = 0;
private static void dfs(boolean[] visited, String[] strings, int cur) {
if (cur == n) {
count++;
return;
}
String curS = strings[cur];
for (int i = 0; i < curS.length(); i++) {
int tmp = curS.charAt(i) - '0';
if (!visited[tmp]) {
visited[tmp] = true;
dfs(visited, strings, cur + 1);
visited[tmp] = false;
}
}
}
}
//答案是我抄的
//回溯法
import java.util.HashSet;
import java.util.Scanner;
public class Main{
private static int result = 0; //需要将result作为全局变量,result为情况种类
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* 6
012345 012345 012345 012345 012345 012345
*/
/*
* 使用回溯法,回溯法利用递归特性,将路径看做栈,当前n-1个都符合情况,在n的时候不符合情况的时候
* 回溯到n-2的时候,重新定义n-1递归
*/
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
String [] array = new String [n]; // 输入,012345存入array[i]中
for(int i = 0;i < n;i++){
array[i] = scanner.next();
}
//computing
backtracing(array,0,new HashSet<>()); //创建新的hashset保存已经被选了的工作
System.out.println(result);
}
public static void backtracing(String [] array,int index,HashSet<Integer> set){
if(index >= array.length){ //递归出口,找到一个可行解,则result++再return
result++;
System.out.println("array,length = "+array.length);
return;
}
String arraynew = array[index];
for(int i = 0;i < arraynew.length();i++){
int work = arraynew.charAt(i) - '0';
if(!set.contains(work)){
set.add(work);
backtracing(array, index+1, set);
set.remove(work);
}
}
}
}
#include<iostream>#include<vector>#include<algorithm>#include<string>using namespace std;intplace(vector<vector<int>>& v, intstart, vector<int>& visited);intmain() {intn;cin >> n;vector<vector<int>> v;for(inti = 0; i < n; ++i) {vector<int> vec;string s;cin >> s;for(intj = 0; j < s.size(); ++j) {vec.push_back(s[j] - '0');}v.push_back(vec);}vector<int> visited(6, 0);intres = place(v, 0, visited);cout << res << endl;}intplace(vector<vector<int>>& v, intstart, vector<int>& visited) {if(start == v.size()) {return1;}intres = 0;for(inti = 0; i < v[start].size(); ++i) {intnum = v[start][i];if(visited[num] == 0) {visited[num] = 1;res += place(v, start + 1, visited);visited[num] = 0;}}returnres;}
import java.util.*;
public class Main
{
public static void main(String[] args)
{
Scanner in=new Scanner(System.in);
int n=in.nextInt();
in.nextLine();
String[] skills=new String[n];
for(int i=0;i<n;i++)
{
skills[i]=in.nextLine();
}
HashSet<Character> done=new HashSet<Character>();
System.out.println(getTaskAllocationNum(skills,0,done));
}
public static int getTaskAllocationNum(String[] skills,int index,HashSet<Character> done)
{
if(index==skills.length)
{
return 1;
}
else
{
int num=0;
for(int i=0;i<skills[index].length();i++)
{
if(!done.contains(skills[index].charAt(i)))
{
done.add(skills[index].charAt(i));
num+=getTaskAllocationNum(skills,index+1,done);
done.remove(skills[index].charAt(i));
}
}
return num;
}
}
} #include <iostream>
#include <vector>
#include <string>
using namespace std;
void dfs(vector<string>& person, vector<int>& task, int taskcount, int& res, int next){
if(taskcount==person.size()){
res++;
return;
}
int i=next,j,n=person.size();
int m = person[i].size();
for(j=0;j<m;j++){
if(task[person[i][j]-'0']==0){
task[person[i][j]-'0']=1;
dfs(person,task,taskcount+1,res,next+1);
task[person[i][j]-'0']=0;
}
}
}
int main(){
int n;
cin>>n;
string s="";
vector<string> person(n,s);
vector<int> task(6,0);
int res=0;
for(int i=0;i<n;i++){
cin>>s;
person[i]=s;
}
dfs(person,task,0,res,0);
cout<<res<<endl;
return 0;
} package Wangyi2017;
import java.util.Scanner;
public class WorkArrange {
public static int res=0;
public static int [] a=new int[6];
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext())
{
int n=sc.nextInt();
String []arr=new String[n];
sc.nextLine();
for(int i=0;i<n;i++)
{
arr[i]=sc.nextLine();
}
arrange(arr,n);
System.out.println(res);
res=0;
}
sc.close();
}
public static void arrange(String []arr,int n)
{
if(n==0)
{
res++;
return;
}
for(int i=0;i<arr[n-1].length();i++)
{
if(a[arr[n-1].charAt(i)-'0']!=0)
{
continue;
}
else {
a[arr[n-1].charAt(i)-'0']=1;
arrange(arr, n-1);
a[arr[n-1].charAt(i)-'0']=0;
}
}
}
}