Skip to main content
  1. Posts/

uva 156 - Ananagrams

·2 mins
Note: This article is available in Chinese only. 本文暂无英文版本。 View original

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=92 题意:给出一段文字,包含若干个单词,以’#‘结束。按照字典序输出所有的ananagrams。所谓ananagram,是指经过任意的重排后,不能得到这段文字中的另一个单词(不区分大小写) 思路:首先是字符串的读入…可以整行读入然后用空格分隔单词。由于补区分大小写,所以要都转化成小写…但是输出的时候要输出原始,所以还记得保留一份。而且要能够通过新的找到原始的(我用了一个toori的map<string,string>来实现) 然后最关键的部分是如何判断两个单词经过重排是否能一样…

我的做法是构造一个hash函数…一个单词的hash值等于对应字母的顺序的平方和…效果还不错?

单词和hash值一一对应…最大也就9E5,可以存的下。然后统计每个hash值出现的次数。对于那些只出现一次的,就是我们要的答案。

还要注意的是输出要按照原始单词的字典序,而不是都变成小写以后的字典序。

所以找到之后可以先找到对应的原始单词存到set里,最后再输出。

  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年01月25日 星期一 14时26分38秒
  4File Name :code/uva/156.cpp
  5************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define fst first
 20#define sec second
 21#define lson l,m,rt<<1
 22#define rson m+1,r,rt<<1|1
 23#define ms(a,x) memset(a,x,sizeof(a))
 24typedef long long LL;
 25#define pi pair < int ,int >
 26#define MP make_pair
 27
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33const int N=9E5+7;
 34string str;
 35int a[N];
 36map<string,int>mp;
 37map<string,int>::iterator it;
 38map<string,string>toori;
 39struct node
 40{
 41    string ori;
 42    string nw;
 43}st[1005];
 44
 45set<string>ans;
 46set<string>::iterator it2;
 47
 48int main()
 49{
 50	mp.clear();
 51	ans.clear();
 52	#ifndef  ONLINE_JUDGE
 53	freopen("code/in.txt","r",stdin);
 54  #endif
 55	ms(a,0);
 56	int cnt = 0 ;
 57	while (getline(cin,str))
 58	{
 59	    if (str=="#") break;
 60	    int p = str.find(' ');
 61	    string tmp;
 62	    int len;
 63	    int num;
 64	    while (p!=-1)
 65	    {
 66	        tmp = str.substr(0,p);
 67	//	cout<<"tmp:"<<tmp<<endl;
 68	//	if (tmp=="") continue;
 69		cnt++;
 70		st[cnt].ori = tmp;
 71
 72	        len = tmp.length();
 73	        num = 0;
 74
 75		for ( int i = 0 ; i < len ; i ++)
 76		{
 77		    tmp[i]=tolower(tmp[i]);
 78		    int val = tmp[i]-'a'+1;  //a..z对应1..26
 79		    num +=val*val;
 80		}
 81	//	cout<<"tmp:"<<tmp<<endl;
 82		st[cnt].nw = tmp;
 83		toori[st[cnt].nw]=st[cnt].ori;
 84		mp[tmp] = num;
 85		a[num]++;
 86		str.erase(0,p+1);
 87		p = str.find(' ');
 88	    }
 89	    //cout<<"rstr:"<<str<<endl;
 90	    tmp=str.substr(0);
 91	    cnt++;
 92	    st[cnt].ori=tmp;
 93	     len = tmp.length();
 94	     num = 0 ;
 95	    for ( int i = 0  ; i < len ; i++)
 96	    {
 97		tmp[i]=tolower(tmp[i]);
 98		int val = tmp[i]-'a'+1;
 99		num +=val *val;
100	    }
101	  //  cout<<"tmp:"<<tmp<<endl;
102	    st[cnt].nw = tmp;
103	    toori[st[cnt].nw]=st[cnt].ori;
104	    mp[tmp]=num;
105	    a[num]++;
106	}
107//	cout<<"a[drIed]:"<<a[mp["dried"]]<<endl;
108	for ( it=mp.begin() ;it!=mp.end(); it ++)
109	{
110	    int tmp = it->sec;
111	  //  cout<<"a[tmp]:"<<a[tmp]<<endl;
112	    if (a[tmp]==1)
113	    {
114		//	cout<<toori[it->fst]<<endl;
115//		cout<<it->fst<<" "<<it->sec<<" "<<toori[it->fst]<<endl;
116		ans.insert(toori[it->fst]);
117	    }
118	}
119	for ( it2=ans.begin() ; it2!=ans.end();it2++)
120	{
121	    cout<<*it2<<endl;
122	}
123
124
125
126  #ifndef ONLINE_JUDGE
127  fclose(stdin);
128  #endif
129    return 0;
130}

Related

hdoj4391 Paint The Wall

·2 mins
http://acm.hdu.edu.cn/showproblem.php?pid=4391 题意:有 n 个点,每个点有一种颜色(可能相同),两种操作:1、将区间 [a,b] 染成颜色 c ; 2、询问区间 [a,b] 中颜色为 c 的点有多少个。 思路:因为颜色种类很多。。。没办法通过建很多棵线段树解决。我们用分块的办法。。。

uva 409 - Excuses, Excuses!

·2 mins
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid;=8&page;=show_problem&problem;=350 题意:给出k个key word,e个借口…找出包含key word最多的借口,即为最坏的借口。匹配补区分大小写&&同一个key word算多次。 思路:需要注意的是因为不区分大小写,需要都转化成大写或者小写。。但是输出的时候要输出原始的。。所以要另外存一份。

hdu 5611 || BC #69 div2 1002 Baby Ming and phone number

·2 mins
http://acm.hdu.edu.cn/showproblem.php?pid=5611 题意:给出n个电话号码(长度为11的字符串),满足特殊条件的价格为a,否则为b.特殊条件为最后5位数字一样,最后5位严格递增或者严格递减,最后8位是一个1980年1月一日到2016年12月31日的合法日期。问最后的价值。

uva 537 Artificial Intelligence?

·2 mins
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid;=8&page;=show_problem&problem;=478 题意:给出一段文字。。其中包含了 P,U,I(功率,电压,电流)中的两个。。求第三个。 思路:字符串处理。。第一次用vim复制整段代码。。命令模式下按v,然后光标扫过的区域都会选中,按y就就复制到剪贴板了。。 所以虽然代码写了300行但只有100行是需要写的。。200行复制改下就好== WA了两次。。一次是因为I写成了小写。。另一次是因为多组数据记得初始化多次。

uva 10010 - Where's Waldorf?

·3 mins
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=951 题意:给出一个由大小写字母组成的二维maze…给出k个询问。每个询问一个单词。问能否在maze中找到这个单词。不区分大小写。输出开头字母的坐标(从1开始)。如果有多组输出最上面的。如果还有多组,输出最左边的。数据保证至少有一组。 思路:直接找就好了。。。坑的地方是。。。格式。。数据组数之后会有一个空行。然后每两组读入数据之间会有一个空行。。输出的时候每两组数据之间也有一个空行。