主题:第34次编程比赛第2题
太没劲了 [专家分:2050] 发布于 2006-07-07 12:51:00
问题描述:
某人有一个奇怪的嗜好,就是看见一个单词就有找它所有的变位词的冲动。一个单词的变位词就是该单词所有字母的一个排列(单词中字母可能重复)。
输入输出格式:
输入数据第一行为一个整数n,1<=n<=10^5,之后n行每行只包含一个单词,不含词组。这些单词构成了字典。每个单词长度不大于9个字母。接着一行为一个整数m,1<=m<=100,表示将看见的单词数。之后 m 行每行包含一个单词。(题目中出现的每个单词都只由小写字母和 '-' 组成,可能字符 27 个)
对应随后看到的每个单词,输出落在字典里的它的变位词的个数。
输入样例
3
tea
ate
eat
3
ate
abc
eat
输出样例
3
0
3
通过标准输入/输出进行输入/输出。
关于题目有任何问题到如下处提:
http://www.programfan.com/club/showbbs.asp?id=179992
回复列表 (共11个回复)
沙发
太没劲了 [专家分:2050] 发布于 2006-07-07 12:53:00
test
板凳
iAkiak [专家分:8460] 发布于 2006-07-07 14:34:00
#include <cstdio>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
#pragma warning(disable:4786)
int main()
{
int n, i;
char buf[10];
map<string, int> ct;
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%s", buf);
string k(buf);
sort(k.begin(), k.end()); // 把字符串排序作为key
ct[k]++;
}
scanf("%*d");
while(scanf("%s", buf) == 1)
{
string k(buf);
sort(k.begin(), k.end());
printf("%d\n", ct[k]);
}
return 0;
}
3 楼
diycai [专家分:1590] 发布于 2006-07-07 17:08:00
#include <stdio.h>
#include <stdlib.h>
int compare(char *a,char *b)
{
int i,j,k,n;
for(i=n=0;a[i];i++)
{
for(j=0,k=1;b[j];j++,k<<=1)
{
if(a[i]==b[j] && !(n&k))
{
n|=k;
break;
}
}
if(!b[j]) return 0;
}
if(a[i]==b[i]&&n==(1<<i)-1)
return 1;
else
return 0;
}
void main()
{
int i,j,n,m,x;
char *book,*word;
scanf("%d",&n);
book = (char *)malloc( n*10*sizeof(char) );
for(i=0;i<n;i++)
{
scanf("%s",book+i*10);
}
scanf("%d",&m);
word = (char *)malloc( m*10*sizeof(char) );
for(i=0;i<m;i++)
{
scanf("%s",word+i*10);
}
for(i=0;i<m;i++)
{
for(j=x=0;j<n;j++)
{
if(compare(book+j*10,word+i*10))
x++;
}
printf("%d\n",x);
}
free( book );
free( word );
}
4 楼
天边蓝 [专家分:1810] 发布于 2006-07-07 19:19:00
#include<iostream>
#include<string>
#include<list>
#include<algorithm>
using namespace std;
int main(){
int m,n;
string s;
list<string> slist;
int *res;
cin>>m;
for(int i=0;i<m;i++){
cin>>s;
slist.insert(slist.begin(),s);
}
cin>>n;
res=new int[n];
for(i=0;i<n;i++)
res[i]=0;
for(i=0;i<n;i++){
cin>>s;
sort(s.begin(),s.end());
if( find(slist.begin(),slist.end(),s )!=slist.end())
res[i]++;
while(next_permutation(s.begin(),s.end()) ){
if( find( slist.begin(),slist.end(),s)!=slist.end())
res[i]++;
}
}
for(i=0;i<n;i++)
cout<<res[i]<<endl;
return 0;
}
5 楼
混混兔 [专家分:1600] 发布于 2006-07-08 03:46:00
我只是想发个言,仅仅提个我对题目的看法,LZ不用把我的参加此比赛
对于用于查找的单词,应该不需要生成它的所有排列,如果去生成的话,会浪费很多时间,因此,直接把单词与字典去比较。
设:被查找单词a,字典单词b,长度与单词b一样的标志数组c
取出单词a的第一个字母,到单词b中找到该字母且该字母对应的标志数组c未被设置,z找到后在该字母对应的c数组上设置一个标志,代表以被查找,然后取出单词a中的第二个字母,同样也是在单词b中查找该字母,如果当单词a中的某一个字母,在b中却找不到标志未被设置同一字母,则单词b就不会是单词a的变位词,查找完所有a字母都能在b中找到的话,则判断单词b与单词a的长度,如果相等则b一定是a的变位词。
6 楼
nwpuzhl [专家分:0] 发布于 2006-07-08 04:13:00
#include "stdio.h"
#include "string.h"
#define M 10
#define N 100000
char a[N][10];
long len;
long numberOfString(char *,int length);
int iS(char *,int ,char *);
void sort(char *,int);
int main(){
char c[M];
long numberOf=0;
int i=0;
int num;
scanf("%ld",&len);
for(i=0;i<len;i++)
scanf("%s",a[i]);
scanf("%d",&num);
for(i=0;i<num;i++) {
scanf("%s",c);
numberOf=numberOfString(c,strlen(c));
printf("%ld\n",numberOf);
numberOf=0;
}
return 0;
}
long numberOfString(char *c,int length){
long number=0;
int i;
for(i=0;i<len;i++)
if(length==strlen(a[i]))
number+=iS(c,length,a[i]);
return number;
}
int iS(char *c,int length,char *d){
int i=0,j=0;
char e;
int sumOne=0,sumTwo=0;
for(i=0;i<length;i++) {
sumOne+=c[i];
sumTwo+=d[i];
}
if(sumOne!=sumTwo) return 0;
sort(c,length);
for(i=0;i<length;i++) {
for(j=i+1;j<length;j++)
if(d[i]>d[j]){e=d[i];d[i]=d[j];d[j]=e;}
if(d[i]!=c[i]) return 0;
}
return 1;
}
void sort(char *c,int length) {
int i = 0,j=0;
char e;
for(i=0;i<length;i++)
for(j=i+1;j<length;j++)
if(c[i]>c[j]) {e=c[i];c[i]=c[j];c[j]=e;}
return ;
}
7 楼
sllone [专家分:150] 发布于 2006-07-08 22:20:00
//34次编程比赛第二题
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
class Dictionary_searcher{//字典查寻类
private:
int *Dictionary;//字典,n行3列数组,每行为一个类型变位词,1,2列保存单词的特征码,0列保存具有相同特征码(同一变位词)的单词数
unsigned int info[26];
unsigned int word_code1,word_code2;//一组变位词的两个特征码
public:
Dictionary_searcher(istream &);
~Dictionary_searcher();
void Instial_Dictionary(istream &);//输入构造字典
void Words_search(istream &,ostream &);//查寻输入系列单词
void Word_Chg(string &);//把单词编码
int Search_Word();//根据单词两个特征码在字典中找到位置
};
Dictionary_searcher::~Dictionary_searcher(){//有些数据(3 eat teeea aeet 2 tea eat)会出现运行期意外,但结果没错,
delete[] Dictionary; //出错点也在这析构函数这,改了很久,刚学用c++,
} //算法该没问题,请楼主费点心,看看,感谢
Dictionary_searcher::Dictionary_searcher(istream &in){
info[0]=1;
for(int i=1;i<26;i++)
info[i]=(1<<i);
word_code1=0;
word_code2=0;
Instial_Dictionary(in);
}
void Dictionary_searcher::Instial_Dictionary(istream &in){
string buff;
int j=0,tmp,k;
in>>buff;
k=atoi(buff.c_str());
Dictionary=new int[k*3];
Dictionary[0]=0;
Dictionary[1]=0;
Dictionary[2]=0;
for(int i=0;i<k;i++){
in>>buff;
Word_Chg(buff);
if((tmp=Search_Word())==-1){
Dictionary[j*3+0]++;
Dictionary[j*3+1]=word_code1;
Dictionary[j*3+2]=word_code2;
j++;
Dictionary[j*3+0]=0;
Dictionary[j*3+1]=0;
Dictionary[j*3+2]=0;
}
else Dictionary[tmp*3+0]++;
}
}
int Dictionary_searcher::Search_Word(){
int i=0;
while(Dictionary[i*3+0]!=0){
if(word_code1==Dictionary[i*3+1]&&word_code2==Dictionary[i*3+2])
return i;
i++;
}
return -1;
}
void Dictionary_searcher::Word_Chg(string &buff){
int i=0,tmp;
unsigned int temp[26]={0};
word_code1=0;
word_code2=0;
while(i<buff.size()){
tmp=(buff[i]-97)%26;
word_code1|=info[tmp];
temp[tmp]++;
i++;
}
i=0;
tmp=1;
while(i<26){
while(temp[i]>1){
word_code2+=(tmp*=8);
temp[i]--;
}
i++;
}
}
void Dictionary_searcher::Words_search(istream &in,ostream &out){
string buff;
int tmp,k,j=0;
int*p;
in>>buff;
k=atoi(buff.c_str());
p=new int[k];
for(int i=0;i<k;i++,j++){
in>>buff;
Word_Chg(buff);
tmp=Search_Word();
p[j]=(tmp!=-1?Dictionary[tmp*3+0]:0);
}
for(k=0;k<j;k++)
out<<p[k]<<endl;
delete[] p;
}
void main(){
Dictionary_searcher D(cin);
D.Words_search(cin,cout);
}
8 楼
yxs0001 [专家分:9560] 发布于 2006-07-09 09:18:00
#include <iostream>
#include <string>
using namespace std;
const int N = 10;
const int NUM = 500000;
struct WordCode{
int high;
int low;
int times;
// char word[N];
WordCode(){};
WordCode(char *p);
bool operator >(WordCode &wordcode);
bool operator <(WordCode &wordcode);
bool operator ==(WordCode &wordcode);
};
WordCode::WordCode(char *p)
{
int l = strlen(p),temp,i,j;
for(i=0;i<l;i++)
for(j=i+1;j<l;j++){
if(p[i]>p[j]){
char c = p[i];
p[i] = p[j];
p[j] = c;
}
}
// strcpy(word,p);
high = low = 0;
temp = (l<5) ? l : 5;
for(i=0;i<temp;i++)
high |= (((p[i] == '-') ? 1 : (p[i] - '\x5f')) << (i*5));
for(i=5;i<temp;i++)
low |= (((p[i] == '-') ? 1 : (p[i] - '\x5f')) << ((i-5)*5));
times = 1;
}
bool WordCode::operator >(WordCode &wordcode)
{
if(high>wordcode.high)
return true;
if(high<wordcode.high)
return false;
if(low>wordcode.low)
return true;
return false;
}
bool WordCode::operator <(WordCode &wordcode)
{
if(high<wordcode.high)
return true;
if(high>wordcode.high)
return false;
if(low<wordcode.low)
return true;
return false;
}
bool WordCode::operator ==(WordCode &wordcode)
{
if(high==wordcode.high && low==wordcode.low)
return true;
return false;
}
class CDictionary{
private :
int words;//词数
WordCode code[NUM];
public:
int find_word(WordCode *wordcode,int &pos);//返回>=该词的下标
void add(char *p);
void show();
CDictionary(){words = 0;};
};
void CDictionary::show()
{
cout<<"\n字典:\n";
for(int i=0;i<words;i++){
cout.width(3);
cout<<i;
cout.width(10);
cout<<code[i].word;
cout.width(10);
cout<<code[i].high;
cout.width(10);
cout<<code[i].low;
cout.width(5);
cout<<code[i].times<<endl;
}
}
int CDictionary::find_word(WordCode *wordcode,int &pos)
{
int start = 0,end = words,mid;
if(code[start] == *wordcode){
pos = start;
return code[pos].times ;
}
if(code[end] == *wordcode){
pos = end;
return code[pos].times ;
}
while(start <= end){
mid = (start + end)/2;
if(code[mid] == *wordcode){
pos = mid;
return code[pos].times ;
}
else if(code[mid] < *wordcode)
end = mid - 1;
else
start = mid + 1;
}
pos = start;
return 0;
}
void CDictionary::add(char *p)
{
WordCode wordcode(p);
int pos;
if(find_word(&wordcode,pos))
code[pos].times ++;
else{
words ++;
for(int i = words;i>=pos;i--)
code[i] = code[i-1];
code[pos] = wordcode;
}
}
int main()
{
CDictionary *dict = new CDictionary;
int allwords,i,pos;
char str[N];
// cout<<"请输入字典词数:";
cin>>allwords;
i = 0;
while(i<allwords){
i++;
cin>>str;
dict->add(str);
// dict->show();
}
// cout<<"请输入查找词数:";
cin>>allwords;
i = 0;
while(i<allwords){
i++;
cin>>str;
WordCode wordcode(str);
cout<<dict->find_word(&wordcode,pos)<<endl;
// cout<<"在字典中出现了 "<<dict->find_word(&wordcode,pos)<<" 次"<<endl;
}
return 0;
}
9 楼
magicalking [专家分:150] 发布于 2006-07-09 12:16:00
我用的是devcpp
本人是新手,献丑了[em11]
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
using namespace std;
typedef string word;
typedef vector<word> words;
void dict(words& dic){
int i;
word wd;
cin>>i;
string::iterator it;
for(int j=0;j<i;j++){
cin>>wd;
sort(wd.begin(),wd.end());
it=unique(wd.begin(),wd.end());
wd.erase(it,wd.end());
dic.push_back(wd);
}//for end
}
void words_to(words& to_tran){
int i;
word wd;
cin>>i;
string::iterator it;
for(int j=0;j<i;j++){
cin>>wd;
sort(wd.begin(),wd.end());
it=unique(wd.begin(),wd.end());
wd.erase(it,wd.end());
to_tran.push_back(wd);
}//for end
}
void judge(words& dic,words& to_tran){
words::iterator it1=dic.begin(),it2=to_tran.begin();
int count=0;
for(;it2!=to_tran.end();count=0,it2++,it1=dic.begin()){
for(;it1!=dic.end();it1++)
if(*it2==*it1)
count++;
cout<<count<<endl;
}//for1 end
}
main(){
words dic,to_tran;
dict(dic);
words_to(to_tran);
judge(dic,to_tran);
while(1);
}
10 楼
SonicLing [专家分:6260] 发布于 2006-07-09 18:32:00
#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
#include <iterator>
class WordDescriptor
{
public:
enum {MaxLen = 9};
WordDescriptor() : _count(0) {}
WordDescriptor(const char * word) : _count (1)
{
/*
Key algorithm, it sorts the word, and treats the result
as the essense of the word. If the essenses of two words
are equal, we say the words are equivalent to each other.
*/
size_t len = strlen(word);
if(len > MaxLen) len = MaxLen;
memcpy(_word, word, len+1);
std::sort(_word, _word+strlen(_word));
}
// copy constructor
WordDescriptor(const WordDescriptor &wd) : _count(wd._count)
{ memcpy(_word, wd._word, MaxLen+1); }
// compare essense to another word
bool IsSimilar(const char * word) const
{ return *this == WordDescriptor(word); }
// counting operations
void Increase() { _count++; }
int GetCount() { return _count; }
// copy operator
WordDescriptor & operator = (const WordDescriptor &wd)
{
_count = wd._count;
memcpy(_word, wd._word, MaxLen+1);
return *this;
}
// a sort of comparing operation
bool operator < (const WordDescriptor &wd) const
{ return strcmp(_word, wd._word) < 0; }
bool operator <= (const WordDescriptor &wd) const
{ return strcmp(_word, wd._word) <= 0; }
bool operator > (const WordDescriptor &wd) const
{ return strcmp(_word, wd._word) > 0; }
bool operator >= (const WordDescriptor &wd) const
{ return strcmp(_word, wd._word) >= 0; }
bool operator == (const WordDescriptor &wd) const
{ return strcmp(_word, wd._word) == 0; }
bool operator != (const WordDescriptor &wd) const
{ return strcmp(_word, wd._word) != 0; }
bool operator == (const char * &word) const
{ return IsSimilar(word); }
private:
char _word[MaxLen+1];
int _count;
};
typedef std::list<WordDescriptor> WDscptors;
typedef std::list<WordDescriptor>::iterator WDIterator;
typedef std::vector<int> IntArray;
void RegisterWord(WDscptors &dscors, const char * word)
{
/*
algorithm for recording words from dictionary. it use
binary search algorithm to find the potential position of the
word in descriptor(essense) list, if found it, increase it;
otherwise, insert the essense of this word to that position.
NOTE: the potential position return by searching function is the
position that the target would be present if it is in the range.
see STL documents for more details.
*/
WordDescriptor wd(word);
WDIterator it = std::lower_bound(dscors.begin(), dscors.end(), wd);
if( *it != wd ) dscors.insert(it, wd);
else return it->Increase();
}
int FindWords(WDscptors &dscors, const char * word)
{
/*
this algorithm is similar to RegisterWord function.
*/
WordDescriptor wd(word);
WDIterator it = std::lower_bound(dscors.begin(), dscors.end(), wd);
if( *it != wd ) return 0;
else return it->GetCount();
}
using namespace std;
void PrintInteger(int a)
{ cout << a << endl; }
int main(int argc, char *argv[])
{
WDscptors wds;
IntArray intlist;
int dicsize, words;
char word[WordDescriptor::MaxLen+1];
// record essenses of the words from dictionary to
// descriptor(essense) list.
cin >> dicsize;
// wds.resize(dicsize, WordDescriptor()); // abandoned when use list
for(int i=0; i<dicsize; i++)
{
cin >> word;
RegisterWord(wds, word);
}
// calculate present times of every target words,
// and restore the present times to a vector,
// which holds all the results ordinally.
cin >> words;
intlist.resize(words, 0);
for(int i=0; i<words; i++)
{
cin >> word;
intlist[i] = FindWords(wds, word);
}
// print the vector
for_each(intlist.begin(), intlist.end(), PrintInteger);
//system("PAUSE");
return 0;
}
我来回复