输入的第一行为以空格分隔的两个正整数,第一个表示原始美味总数n,第二个表示前置菜肴范式总数m。 其后m行每行均为一个以空格分隔的范式说明,第一列为待吃菜肴的标号,第二列为前置菜肴的标号。
对每组测试数据,单独输出一行答案,菜肴标号之间用英文逗号分隔。
4 4 1 0 2 0 3 1 3 2
只需输出以下任一种结果即可 0,1,2,3 或 0,2,1,3
while (!myStack.empty()){
package zhaohang; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class ProblemMeishi { //i:dish的下标、list 结果集 public static boolean process(int n, List<Integer> dish, List<Integer> beforeDish, int[] beforeDishNum, int i, List<Integer> list, List<Integer> processList) { if (processList.contains(beforeDish.get(i))) // 如果成环了,就直接返回false return false; if (list.contains(beforeDish.get(i))) { // 如果当前菜肴未吃,但前置菜肴已吃 if (beforeDishNum[dish.get(i)] == 1){ // 表示前置菜肴只需要1个 list.add(dish.get(i)); } else // 表示前置菜肴需要多个 beforeDishNum[dish.get(i)]--; return true; } else { processList.add(dish.get(i)); if (process(n, dish, beforeDish, beforeDishNum, dish.indexOf(beforeDish.get(i)), list, processList)){ // 不成环,表示能吃完,做进一步处理 processList.remove(dish.get(i)); // 前置菜肴吃完,继续来吃这道菜 process(n, dish, beforeDish, beforeDishNum, i, list, processList); } } return false; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); // 原始美味总数n int n = sc.nextInt(); // 前置菜肴范式总数m int m = sc.nextInt(); // 第一列待吃菜肴编号,下标无用 List<Integer> dish = new ArrayList<>(); // 第二列前置菜肴编号,下标无用 List<Integer> beforeDish = new ArrayList<>(); // 每种菜需要的前置菜个数,下标对应着菜肴标号 int[] beforeDishNum = new int[n]; for (int i = 0; i < m; i++) { dish.add(sc.nextInt()); beforeDish.add(sc.nextInt()); beforeDishNum[dish.get(i)]++; } for (int i = 0; i < m; i++) { // 如果前置菜肴是自己 则不可能吃完 if (dish.get(i) == beforeDish.get(i)) { System.out.println("None"); return; } } List<Integer> list = new ArrayList<>(); for (int i = 0; i < n; i++) { if (beforeDishNum[i] == 0) { // 如果不需要前置菜肴,直接吃,记录到list里 list.add(i); } } // 防止成环 List<Integer> processList = new ArrayList<>(); // m个菜肴都是需要前置菜肴的 for (int i = 0; i < m; i++) { if (list.contains(dish.get(i))) // 如果菜肴已在递归中吃过,则跳过该菜肴 continue; process(n, dish, beforeDish, beforeDishNum, i, list, processList); } // 打印 if (list.size() == n) { for (int i = 0; i < list.size() - 1; i++) { System.out.print(list.get(i) + ","); } System.out.print(list.get(list.size() - 1)); } else System.out.println("None"); } }
#include <bits/stdc++.h> using namespace std; vector<int> path;//存储吃东西顺序的路径 int n, m; bool found;//是否已找到解 vector<unordered_set<int> > limit;//limit[i]:存吃第i个东西前必须先吃的 bool find(int index, int dest) {//此函数用于搜寻某号食物是否已经吃了 bool ans = false; for (int i = 0; i < index; ++i) { if (path[i] == dest) { ans = true; break; } } return ans; } void dfs(int index) {//深度优先搜索 if (!found) { if (index >= n) {//如果已经到了最后,打印结果并将found置true for (int i = 0; i < n; ++i) printf("%d%c", path[i], i==n-1 ? '\n' : ','); found = true; } else {//否则要作进一步搜索 for (int i = 0; i < n; ++i) { if (find(index, i))//如果编号为i的东西已经吃了,则跳过 continue; bool visitable = true; //visitable用来确定吃i号东西前要先吃的东西有没有吃 for (auto it = limit[i].begin(); it != limit[i].end(); ++it) { if (!find(index, *it)) { visitable = false; break; } } if (visitable) { path[index] = i; dfs(index + 1); } } } } } int main() { while (scanf("%d %d", &n, &m) != EOF) { found = false; path.clear(); path.resize(n, -1); limit.clear(); limit.resize(n); int x, y; for (int i = 0; i < m; ++i) { scanf("%d %d", &x, &y); limit[x].insert(y); } dfs(0); if (!found) printf("None\n"); } return 0; }
using namespace std;int flagover = 0;
//1表示可以被吃掉//0表示不可以被吃掉
有80%的通过,不知道逻辑上还有什么漏洞,求大家指点! import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; class caipin{ int bianhao; ArrayList<Integer> pre=new ArrayList(); public caipin(int a){ this.bianhao=a; } public void insert(int a){ pre.add(a); } } public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in); int number1=sc.nextInt(); int number2=sc.nextInt(); ArrayList<Integer> re=new ArrayList(); re.add(-1); //定义caipin的对象数组 caipin [] rr=new caipin[number1]; //因为菜一定是n道菜 //所以先创建好对象数组 for(int i=0;i<number1;i++){ caipin a=new caipin(i); rr[i]=a; } for(int i=0;i<number2;i++){ int origion=sc.nextInt(); int pre=sc.nextInt(); rr[origion].insert(pre); } //遍历对象数组,先判断是否能吃下所有美食 for(int i=0;i<number1;i++){ for(int j=0;j<rr[i].pre.size();j++){ //如果一个菜品的前置菜肴还包含它自己,那么就不可能吃到所有美食 if(rr[rr[i].pre.get(j)].pre.contains(i)){ System.out.println("None"); break; } else{ //如果可以的话,就给美食排顺序, //排序的时候同样会出现无法吃到所有美食的情况 //首先判断我正要安置的美食是不是已经出现了 if(re.contains(rr[i].bianhao)){ //说明我当前要安置的美食,已经作为别人的前置美食了 //如果我要放置的美食的前置菜肴已经存在,并且就在我要安置的前面 if(re.contains(rr[i].pre.get(j))&&re.indexOf(rr[i].pre.get(j))<re.indexOf(rr[i].bianhao)){ //不用进行操作 } else { if(!re.contains(rr[i].pre.get(j))){ //如果不包含这个前置美食,就把它插入到,已存在的需要安置的美食的前面 re.add(re.indexOf(rr[i].bianhao),rr[i].pre.get(j)); } else{ //如果包含这个前置美食,并且这个前置美食的位置还在我需要安放的美食的位置后面, //尝试能不能把在后面的前置美食往前挪动,如果可以,挪到需要安放的美食前面就说明是可以的 int index1=re.indexOf(rr[i].bianhao); int index2=re.indexOf(rr[i].pre.get(j)); //把后面的往前移动 int aa=0; for(int a=index2-1;a>index1;a--){ if(rr[rr[i].pre.get(j)].pre.contains(re.get(a))){ //如果往前移动发现移动不了 aa=0; break; } else{ aa=1; } } int bb=0; for(int b=index1+1;b<index2;b++){ if(rr[re.get(b)].pre.contains(rr[i].bianhao)){ bb=0; break; } else{ bb=1; } } if(aa==1||bb==1){ int tt=re.get(index1); re.set(index1, re.get(index2)); re.set(index2, tt); } else { System.out.println("None"); break; } } } } else{ //如果需要放置的菜不包含 if(re.contains(rr[i].pre.get(j))){ //如果我放的这个美食的前置美食已经存在,不用操作, } else { //如果不存在 re.add(rr[i].pre.get(j)); } } } } if(re.contains(rr[i].bianhao)){ } else{ re.add(rr[i].bianhao); } } String r=re.get(1)+""; for(int i=2;i<re.size();i++){ r=r+","+re.get(i); } System.out.println(r); } }