UVA - 148

UVA - 148

题目介绍:
It is often fun to see if rearranging the letters of a name gives an amusing anagram. For example, the
letters of ‘WILLIAM SHAKESPEARE’ rearrange to form ‘SPEAK REALISM AWHILE’.
Write a program that will read in a dictionary and a list of phrases and determine which words from
the dictionary, if any, form anagrams of the given phrases. Your program must find all sets of words in
the dictionary which can be formed from the letters in each phrase. Do not include the set consisting
of the original words. If no anagram is present, do not write anything, not even a blank line.

大意:
找单词,使所有对应字母数量相同。且不能和问的单词完全相同。显然是个暴力搜索题,搜出所有答案。只要将字母数量作为定量条件,对每个位置的单词做判断是否能加,在字母数量全为0时判断是否和原问题的单词完全相同即可。

AC代码:

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

string dic[2005];
int num[2005][30]={0};
int n=0,have[10000];
string que;
string cmp;

void dfs(int* now,int cur,int p){
	int k=0;
	for(;k<26;k++)
		if(now[k])
			break;
	if(k>=26){
		string temp="";
		for(int i=0;i<cur;i++)
			temp+=dic[have[i]];
		if(cmp!=temp){
			cout<<que<<" =";
			for(int i=0;i<cur;i++)
				cout<<' '<<dic[have[i]];
			cout<<endl;
		}
		return;
	}
	for(int i=p;i<n;i++){
		int j=0;
		for(;j<26;j++)
			if(num[i][j]>now[j])
				break;
		if(j>=26){
			for(j=0;j<26;j++)
				now[j]-=num[i][j];
			have[cur]=i;
			dfs(now,cur+1,i+1);
			for(j=0;j<26;j++)
				now[j]+=num[i][j];
		}
	}
}

int main(){
	string s;
	while(getline(cin,s)&&s[0]!='#'){
		dic[n]=s;
		for(int i=0;s[i];i++)
			num[n][s[i]-'A']++;
		n++;
	}
	while(getline(cin,que)&&que[0]!='#'){
		int need[30]={0};
		cmp="";
		vector<string> cur;
		string temp="";
		for(int i=0;que[i];i++)
			if(isalpha(que[i])){
				need[que[i]-'A']++;
				temp+=que[i];
			}
			else{
				cur.push_back(temp);
				temp="";
			}
		if(temp.length())cur.push_back(temp);
		sort(cur.begin(),cur.end());
		for(int i=0;i<cur.size();i++)
			cmp+=cur[i];	
		dfs(need,0,0);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值