pat 冬季第4题

本文介绍了一种解决化学方程式的算法设计方案,利用模拟+深度优先搜索(DFS)的方法来找出所有可能的化学反应路径,确保每个反应物只被使用一次,并按最优顺序输出这些路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

掏钱买的考了一下最后一个题目大半天编一点编一点的感觉总是到不了头就睡觉去了 太困了  然后又搭上了晚上  看别人的总感觉思路虽然差不多但是我们实际处理差距还是很大的

所以自己debug自己的代码 最后过了样例 感觉应该是对的

不想再花一份钱弄一下了  有钱的老哥帮我弄一下看看对不对告诉我一下呗

C:\Users\Administrator\AppData\Local\Packages\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\TempState\Downloads\PATï¼ç²çº§ï¼2020å¹´å¬å­£èè¯ Mar 3, 2021 (5).html

一般这种dfs是图论里面的但是本题之所以复杂是因为是模拟+dfs 每个交叉路口需要自己处理信息,实际上以前经常处理图论边相关的交叉路口 但这里是 string 可以才去的方案 的交叉路口就要复杂些

同时dfs 此处未必会到最终点 停下 所以选用 两个pop_back配合的方式行不通了 只能是在交叉路口一个地方pop_back

同时需要去标记   

要清楚自己交叉路口准备的信息是啥样的    标记时就要采取对应的方案

sort  cmp  string的话会直接实现逐项比较 逻辑减轻

之所以没有参考其他答案是因为他们的dfs我无法总结出一个通用的方案  明天我回本对各种情况总结一个在不同情况下的dfs通用方案

7-4

Chemical Equation

(30分)

A chemical equation is the symbolic representation of a chemical reaction in the form of symbols and formulae, wherein the reactant entities are given on the left-hand side and the product entities on the right-hand side. For example, CH4+2O2=CO2+2H2OCH_4 + 2 O_2 = CO_2 + 2 H_2 OCH​4​​+2O​2​​=CO​2​​+2H​2​​O means that the reactants in this chemical reaction are methane and oxygen: CH4CH_4CH​4​​ and O2O_2O​2​​, and the products of this reaction are carbon dioxide and water: CO2CO_2CO​2​​ and H2OH_2 OH​2​​O.

Given a set of reactants and products, you are supposed to tell that in which way we can obtain these products, provided that each reactant can be used only once. For the sake of simplicity, we will consider all the entities on the right-hand side of the equation as one single product.

Input Specification:

Each input file contains one test case. For each case, the first line gives an integer NNN (2≤N≤202 \le N \le 202≤N≤20), followed by NNN distinct indices of reactants. The second line gives an integer MMM (1≤M≤101 \le M \le 101≤M≤10), followed by MMM distinct indices of products. The index of an entity is a 2-digit number.

Then a positive integer KKK (≤50\le 50≤50) is given, followed by KKK lines of equations, in the format:

reactant_1 + reactant_2 + ... + reactant_n -> product

where all the reactants are distinct and are in increasing order of their indices.

Note: It is guaranteed that

  • one set of reactants will not produce two or more different products, i.e. situation like 01 + 02 -> 03 and 01 + 02 -> 04 is impossible;
  • a reactant cannot be its product unless it is the only one on the left-hand side, i.e. 01 -> 01 is always true (no matter the equation is given or not), but 01 + 02 -> 01 is impossible; and
  • there are never more than 5 different ways of obtaining a product given in the equations list.

Output Specification:

For each case, print the equations that use the given reactants to obtain all the given products. Note that each reactant can be used only once.

Each equation occupies a line, in the same format as we see in the inputs. The equations must be print in the same order as the products given in the input. For each product in order, if the solution is not unique, always print the one with the smallest sequence of reactants -- A sequence { a1,⋯,ama_1, \cdots , a_ma​1​​,⋯,a​m​​ } is said to be smaller than another sequence { b1,⋯,bnb_1, \cdots , b_nb​1​​,⋯,b​n​​ } if there exists 1≤i≤min(m,n)1\le i \le min(m,n)1≤i≤min(m,n) so that aj=bja_j=b_ja​j​​=b​j​​ for all j<ij<ij<i, and ai<bia_i<b_ia​i​​<b​i​​.

It is guaranteed that at least one solution exists.

Sample Input:

8 09 05 03 04 02 01 16 10
3 08 03 04
6
03 + 09 -> 08
02 + 08 -> 04
02 + 04 -> 03
01 + 05 -> 03
01 + 09 + 16 -> 03
02 + 03 + 05 -> 08

Sample Output:

02 + 03 + 05 -> 08
01 + 09 + 16 -> 03
04 -> 04
//模拟+dfs 
//首先要保证 格的交叉路口的信息正不正确
//之后是dfs 标记以及路径的问题 
#include<bits/stdc++.h>
using namespace std;
int getp(string a){
	reverse(a.begin(),a.end());
	string temp=a.substr(0,2);
	reverse(temp.begin(),temp.end());
	//debug
	//printf("%d ",stoi(temp)) ;
	return stoi(temp);
}
int book[100];
int book1[100];//ui ys qy kd ve yi crt
string getr(string a){
string _1="";
for(int i=0;i<a.size();i++){
		if(a[i]=='-') break;
		if(isdigit(a[i])){
			_1+=a[i];
			//debug
			//cout<<_1<<" ";
		}
	}
	return _1;
	
}
bool yj(string a){
	
	for(int i=0;i<a.size();i++){
	         string temp=a.substr(i,2);
	         //debug
	         //printf("%s ",temp.c_str());
			if(book[stoi(temp)]!=1||book1[stoi(temp)]!=0){
			return false;
			}
	     	i+=1;	
		
	}
	return true;
}
bool cmp(string a,string b){
	return a<b;
}
map<int,vector<string>> ans; 
vector<string> en,temp;
int flag1=0,cnt;
vector<string> aa[20];
void dfs(int x){
	//end
	if(x==cnt){
		en=temp;
		flag1=1;
		return; 
	}
	for(int i=0;i<aa[x].size();i++){
		if(yj(aa[x][i])&&flag1==0){
			temp.push_back(aa[x][i]);
			//debug
			//cout<<aa[x][i];
			//book1[stoi(aa[x][i])]=1;//标记不是整块出标记
			 for(int j=0;j<aa[x][i].size();j++){
	         string temp=aa[x][i].substr(j,2);
	         
			book1[stoi(temp)]=1;
	     	j+=1;	
		
	        }
			dfs(x+1);
			//book1[stoi(aa[x][i])]=0;//去标记也是这样
			 for(int j=0;j<aa[x][i].size();j++){//要清楚aa里面到底存储的什么 
	         string temp=aa[x][i].substr(j,2);
	         
			book1[stoi(temp)]=0;
	     	j+=1;	
		
	        }
			temp.pop_back();//如果他自己本身都试完了存储路径怎么出 
			//转盘那种单个出的情况走不到最后的情况 
		}
		//temp.pop_back();
	}
	//temp.pop_back();//之前的情况总有到最后的相互配合,这个不一定走到最后所以要另安排出 
}
int main(){
	int n,k,m;
	string _1,_2;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		cin>>_1;
		book[stoi(_1)]=1;
	}
	scanf("%d",&k);
	vector<string> qu;
	for(int i=0;i<k;i++){
		cin>>_2;
		qu.push_back(_2);
	}
	scanf("%d",&m);
	getchar();
	string _11;
	for(int i=0;i<m;i++){
		//getchar();//只需要scanf之前getchar一下而不是每次都getchar 
		getline(cin,_11);
		ans[getp(_11)].push_back(getr(_11));
	}
	 cnt=0;
	for(int i=0;i<qu.size();i++){
		if(book[stoi(qu[i])]==1){
			ans[stoi(qu[i])].push_back(qu[i]);
			}
			sort(ans[stoi(qu[i])].begin(),ans[stoi(qu[i])].end(),cmp);//忘记cmp 
			aa[cnt]=ans[stoi(qu[i])];	
			cnt++;
		
	}
	//debug  aa
	/*for(int i=0;i<cnt;i++){
      for(int j=0;j<aa[i].size();j++)
		printf(" %s",aa[i][j].c_str());
		printf("\n");
	} */
	dfs(0);
	for(int i=0;i<en.size();i++){
		for(int j=0;j<en[i].size();j++){
			if(j!=0) printf(" + ");
			string temp1=en[i].substr(j,2);
			printf("%s",temp1.c_str());
			j++;
		}
		printf(" -> %02d",stoi(qu[i]) );
		printf("\n");
	}
	return 0;
	
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值