buct1766 Following Orders

题目:buct1766   pku1270

方法:dfs

思想:利用搜索或next_permutation产生下一个排列,然后判断该排列是否满足

要求,如果满足要求输出即可。

代码:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
char var[50],t[50];
char constraint[105][2];
bool visited[50];
int n,m,pos[305];
void dfs(int k)
{
	int i,j;
	if(k==n)
	{	
		//更新字符所对应的位置	
		for(i=0;i<m;i++)
 		{	for(j=0;j<n;j++)
 				if(constraint[i][0]==t[j])
 				{ pos[constraint[i][0]]=j; break;}
			for(j=0;j<n;j++)
 				if(constraint[i][1]==t[j])
 				{ pos[constraint[i][1]]=j; break;}
 		}
 		// 看是否存在违背限制的字符对 
 		for(i=0;i<m;i++)
 		{	for(j=pos[constraint[i][0]]-1;j>=0;j--)
 				if(t[j]==constraint[i][1])break;
			if(j>=0)break;
 		}
 		if(i<m)return;//有违背限制的,不需要输出 
 		for(i=0;i<n;i++)
 		  if(i<n-1)cout<<t[i];
		   else cout<<t[i]<<endl; 
		return;
	}
	for(i=0;i<n;i++)
		if(visited[i]==0)
		{
			char tmp=var[k];pos[k]=i;
			t[k]=var[i];visited[i]=1;
			dfs(k+1);
			t[k]=tmp;visited[i]=0;pos[k]=k;
		}
}

int main()
{
	int flag=0;
	char c;
	n=0,m=0;
	while(scanf("%c",&c)!=EOF)
	{
		if(c>='a'&&c<='z')var[n++]=c;
		while((c=getchar())!='\n')
		 if(c!=' '){ var[n]=c;pos[c]=n;n++;} 
	 	while((c=getchar())!='\n')
		 if(c!=' ')
		 {
		 	if(m%2==0)constraint[m/2][0]=c;
		 	else constraint[m/2][1]=c;
		 	m++;
		 }
		 m/=2;
		 int i,j;
		 if(flag)cout<<endl;
		 sort(var,var+n);//必须排序,否则wrong answer 
	 	dfs(0);
	 	n=0;m=0;flag=1;
	}
	return 0;
}
代码二:使用next_permutation

 
#include <iostream>
#include <algorithm>
using namespace std;

int n,m;//n个变量,m个限制 
char var[50];
char constraint[105][2];
int pos[150];

int main(int argc, char *argv[])
{
	int flag=0;
	char c;
	n=0;m=0;
	while(scanf("%c",&c)!=EOF)
	{
		if(c>='a'&&c<='z')var[n++]=c;
		while((c=getchar())!='\n')
		 if(c!=' '){ var[n]=c;pos[c]=n;n++;} 
	 	while((c=getchar())!='\n')
		 if(c!=' ')
		 {
		 	if(m%2==0)constraint[m/2][0]=c;
		 	else constraint[m/2][1]=c;
		 	m++;
		 }
		 m/=2;
		 int i,j;
		 if(flag)cout<<endl;
		 sort(var,var+n);
		 //注意在排列变化的过程中字符对应的位置也要相应更新
		 /*for(i=0;i<m;i++)
		    cout<<constraint[i][0]<<' '<<constraint[i][1]<<endl
			<<pos[constraint[i][0]]<<' '<<pos[constraint[i][1]]<<endl; 
		*/
	 	do
	 	{
	 		//修改排列变化后字符所对应的位置 
	 		for(i=0;i<m;i++)
	 		{	for(j=0;j<n;j++)
	 				if(constraint[i][0]==var[j])
	 				{ pos[constraint[i][0]]=j; break;}
				for(j=0;j<n;j++)
	 				if(constraint[i][1]==var[j])
	 				{ pos[constraint[i][1]]=j; break;}
	 		}
	 		// 看是否存在违背限制的字符对 
	 		for(i=0;i<m;i++)
	 		{	for(j=pos[constraint[i][0]]-1;j>=0;j--)
	 				if(var[j]==constraint[i][1])break;
				if(j>=0)break;
	 		}
	 		if(i<m)continue;
	 		for(i=0;i<n;i++)
	 		  if(i<n-1)cout<<var[i];
			   else cout<<var[i]<<endl; 
	 	}
	 	while(next_permutation(var,var+n));
	 	n=0;m=0;flag=1;
	}
	return 0;
}

这两个代码都只能在buct上AC,在pku上均RE,不知道什么原因,还有待进一步考虑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值