[刷题]算法竞赛入门经典(第2版) 5-10/UVa1597 - Searching the Web
题意:不难理解,照搬题意的解法。
代码:(Accepted,0.190s)
//UVa1597 - Searching the Web
//#define _XIENAOBAN_
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
map<string, set<unsigned> > word;
char lines[1510][85];
unsigned N, M, la[105], ln(1);//la:last line of the article; ln:line number
char tmpword[80], tmpline[88], w1[80], w2[80], w3[80];
void ONLY(bool& flag, const string& on) {
auto &t(word[on]);
auto p(t.begin());
for (unsigned i(1);i <= N;++i) {
while (p != t.end() && *p < la[i - 1]) ++p;
if (p != t.end() && *p < la[i]) {
if (flag) puts("----------");
else flag = true;
while (p != t.end() && *p < la[i])
puts(lines[*p++]);
}
}
}
void NOT(bool& flag, const string& on) {
auto &t(word[on]);
auto p(t.begin());
for (unsigned i(0);i < N;++i) {
while (p != t.end() && *p < la[i]) ++p;
if (p == t.end() || *p >= la[i + 1]) {
if (flag) puts("----------");
else flag = true;
for (auto j(la[i]);j < la[i + 1];++j)
puts(lines[j]);
}
}
}
void AND(bool& flag, const string& le, const string& ri) {
auto &t1(word[le]), &t2(word[ri]);
auto p1(t1.begin()),
p2(t2.begin());
for (unsigned i(1);i <= N;++i) {
while (p1 != t1.end() && *p1 < la[i - 1]) ++p1;
while (p2 != t2.end() && *p2 < la[i - 1]) ++p2;
if ((p1 != t1.end() && *p1 < la[i]) &&
(p2 != t2.end() && *p2 < la[i])) {
if (flag) puts("----------");
else flag = true;
unsigned re;
while ((p1 != t1.end() && *p1 < la[i]) ||
(p2 != t2.end() && *p2 < la[i])) {
if (p1 == t1.end() || *p1 >= la[i]) re = *p2++;
else if (p2 == t2.end() || *p2 >= la[i]) re = *p1++;
else if (*p2 > *p1) re = *p1++;
else if (*p2 < *p1) re = *p2++;
else re = *p1++, *p2++;
puts(lines[re]);
}
}
}
}
void OR(bool& flag, const string& le, const string& ri) {
auto p1(word[le].begin()),
p2(word[ri].begin());
for (unsigned i(1);i <= N;++i) {
while (p1 != word[le].end() && *p1 < la[i - 1]) ++p1;
while (p2 != word[ri].end() && *p2 < la[i - 1]) ++p2;
if ((p1 != word[le].end() && *p1 < la[i]) ||
(p2 != word[ri].end() && *p2 < la[i])) {
if (flag) puts("----------");
else flag = true;
unsigned re;
while ((p1 != word[le].end() && *p1 < la[i]) ||
(p2 != word[ri].end() && *p2 < la[i])) {
if (p1 == word[le].end() || *p1 >= la[i]) re = *p2++;
else if (p2 == word[ri].end() || *p2 >= la[i]) re = *p1++;
else if (*p2 > *p1) re = *p1++;
else if (*p2 < *p1) re = *p2++;
else re = *p1++, *p2++;
puts(lines[re]);
}
}
}
}
int main()
{
#ifdef _XIENAOBAN_
#define gets(T) gets_s(T, 88)
freopen("in.txt", "r", stdin);
#endif
scanf("%d", &N);
getchar();
for (unsigned now(0);now < N;++now) { //read contexts of articles
la[now] = ln;
while (gets(tmpline) && strcmp(tmpline, "**********")) {
strcpy(lines[ln], tmpline);
char *pl(tmpline);
do {
if ((*pl >= 'a' && *pl <= 'z') || (*pl >= 'A' && *pl <= 'Z')) {
char *pw(tmpword);
while ((*pl >= 'a' && *pl <= 'z') || (*pl >= 'A' && *pl <= 'Z')) {
if (*pl >= 'A' && *pl <= 'Z') *pl += 32;
*pw++ = *pl++;
}
*pw = 0;
word[tmpword].insert(ln);
}
} while (*pl++ != 0);
++ln;
}
}
la[N] = ln;
scanf("%d", &M);
getchar();
int nnnn = 0;
while (M--) { //read requests
gets(tmpline);
char *p = tmpline, *pw1 = w1, *pw2 = w2, *pw3 = w3;
while (*p && *p != ' ') *pw1++ = *p++;
*pw1 = '\0';
if (*p) ++p;
while (*p && *p != ' ') *pw2++ = *p++;
*pw2 = '\0';
if (*p) ++p;
while (*p && *p != ' ') *pw3++ = *p++;
*pw3 = '\0';
bool flag(false);
if (!*w2) ONLY(flag, w1);
else if (*w1 == 'N') NOT(flag, w2);
else if (*w2 == 'A') AND(flag, w1, w3);
else OR(flag, w1, w3);
if (!flag) puts("Sorry, I found nothing.");
puts("==========");
//printf("==========%d\n", ++nnnn);//
}
return 0;
}
分析:我选择死亡。。。难倒是不难,很快就解出来了。但是一开始用了近1秒的时间,很郁闷。于是又花了几天的时间去研究别人的代码,也包括把之前sstream全改掉用gets和puts,把only not and or全部分开做函数,写的老长。用gets和puts的版本用了0.600s,还是比别人的都慢好多。GitHub上看到大神0.080s的(https://github.com/morris821028/UVa/blob/master/temp/1597%20-%20Searching%20the%20Web.cpp),我天这是差了多少倍!于是仿着大神的代码也写了个,结果1.090s!!??一定是我没抄到其精髓?!花了几天时间了,结果还变慢了,好难过啊。。。然后过了几天我又回来研究了。我发现其实网上看到的算法全都是大同小异的,那我的代码一定是哪里有问题。看到大神函数里面的这一句:set<int> &t = wordInLine[args[1]]; 一开始我以他只是图个书写方便,但想了想,这样就不需要每次寻找wordInLine[args[1]]的值了,于是我就抱着试试的心态,也加了句类似的。结果瞬间从0.960s降到0.190s!新技能get!
下面是仅仅没有给word[on]、word[le]、word[ri]加引用的版本。
代码:(Accepted,1.090s)
//UVa1597 - Searching the Web
//#define _XIENAOBAN_
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
map<string, set<unsigned> > word;
char lines[1510][85];
unsigned N, M, la[105], ln(1);//la:last line of the article; ln:line number
char tmpword[80], tmpline[88], w1[80], w2[80], w3[80];
void ONLY(bool& flag, const string& on) {
auto p(word[on].begin());
for (unsigned i(1);i <= N;++i) {
while (p != word[on].end() && *p < la[i - 1]) ++p;
if (p != word[on].end() && *p < la[i]) {
if (flag) puts("----------");
else flag = true;
while (p != word[on].end() && *p < la[i])
puts(lines[*p++]);
}
}
}
void NOT(bool& flag, const string& on) {
auto p(word[on].begin());
for (unsigned i(0);i < N;++i) {
while (p != word[on].end() && *p < la[i]) ++p;
if (p == word[on].end() || *p >= la[i + 1]) {
if (flag) puts("----------");
else flag = true;
for (auto j(la[i]);j < la[i + 1];++j)
puts(lines[j]);
}
}
}
void AND(bool& flag, const string& le, const string& ri) {
auto p1(word[le].begin()),
p2(word[ri].begin());
for (unsigned i(1);i <= N;++i) {
while (p1 != word[le].end() && *p1 < la[i - 1]) ++p1;
while (p2 != word[ri].end() && *p2 < la[i - 1]) ++p2;
if ((p1 != word[le].end() && *p1 < la[i]) &&
(p2 != word[ri].end() && *p2 < la[i])) {
if (flag) puts("----------");
else flag = true;
unsigned re;
while ((p1 != word[le].end() && *p1 < la[i]) ||
(p2 != word[ri].end() && *p2 < la[i])) {
if (p1 == word[le].end() || *p1 >= la[i]) re = *p2++;
else if (p2 == word[ri].end() || *p2 >= la[i]) re = *p1++;
else if (*p2 > *p1) re = *p1++;
else if (*p2 < *p1) re = *p2++;
else re = *p1++, *p2++;
puts(lines[re]);
}
}
}
}
void OR(bool& flag, const string& le, const string& ri) {
auto p1(word[le].begin()),
p2(word[ri].begin());
for (unsigned i(1);i <= N;++i) {
while (p1 != word[le].end() && *p1 < la[i - 1]) ++p1;
while (p2 != word[ri].end() && *p2 < la[i - 1]) ++p2;
if ((p1 != word[le].end() && *p1 < la[i]) ||
(p2 != word[ri].end() && *p2 < la[i])) {
if (flag) puts("----------");
else flag = true;
unsigned re;
while ((p1 != word[le].end() && *p1 < la[i]) ||
(p2 != word[ri].end() && *p2 < la[i])) {
if (p1 == word[le].end() || *p1 >= la[i]) re = *p2++;
else if (p2 == word[ri].end() || *p2 >= la[i]) re = *p1++;
else if (*p2 > *p1) re = *p1++;
else if (*p2 < *p1) re = *p2++;
else re = *p1++, *p2++;
puts(lines[re]);
}
}
}
}
int main()
{
#ifdef _XIENAOBAN_
#define gets(T) gets_s(T, 88)
freopen("in.txt", "r", stdin);
#endif
scanf("%d", &N);
getchar();
for (unsigned now(0);now < N;++now) { //read contexts of articles
la[now] = ln;
while (gets(tmpline) && strcmp(tmpline, "**********")) {
strcpy(lines[ln], tmpline);
char *pl(tmpline);
do {
if ((*pl >= 'a' && *pl <= 'z') || (*pl >= 'A' && *pl <= 'Z')) {
char *pw(tmpword);
while ((*pl >= 'a' && *pl <= 'z') || (*pl >= 'A' && *pl <= 'Z')) {
if (*pl >= 'A' && *pl <= 'Z') *pl += 32;
*pw++ = *pl++;
}
*pw = 0;
word[tmpword].insert(ln);
}
} while (*pl++ != 0);
++ln;
}
}
la[N] = ln;
scanf("%d", &M);
getchar();
int nnnn = 0;
while (M--) { //read requests
gets(tmpline);
char *p = tmpline, *pw1 = w1, *pw2 = w2, *pw3 = w3;
while (*p && *p != ' ') *pw1++ = *p++;
*pw1 = '\0';
if (*p) ++p;
while (*p && *p != ' ') *pw2++ = *p++;
*pw2 = '\0';
if (*p) ++p;
while (*p && *p != ' ') *pw3++ = *p++;
*pw3 = '\0';
bool flag(false);
if (!*w2) ONLY(flag, w1);
else if (*w1 == 'N') NOT(flag, w2);
else if (*w2 == 'A') AND(flag, w1, w3);
else OR(flag, w1, w3);
if (!flag) puts("Sorry, I found nothing.");
puts("==========");
//printf("==========%d\n", ++nnnn);//
}
return 0;
}
哎呀呀,就少那么几行,天壤之别。顺便把一开始做的版本也贴了:
代码:(Accepted,0.960s)
//UVa1597 - Searching the Web
#include<iostream>
#include<sstream>
#include<string>
#include<vector>
#include<map>
#include<set>
using namespace std;
struct article {
map<string, vector<unsigned> > word;
vector<string> line;
};
const article tmpart;//an empty article,just for push_back
unsigned N, M;
string tmpstr;
vector<article> dat;
inline bool ONLY(const article& ar, const string& l, const string& r) {
return ar.word.count(l);
}
inline bool AND(const article& ar, const string& l, const string& r) {
return ar.word.count(l) && ar.word.count(r);
}
inline bool OR(const article& ar, const string& l, const string& r) {
return ar.word.count(l) || ar.word.count(r);
}
void NOT(const string& on) {
bool flag(false);
for (const auto& r : dat) {
if (!r.word.count(on)) {
if (flag) cout << "----------\n";
else flag = true;
for (const auto& rr : r.line)
cout << rr << '\n';
}
}
if (!flag) cout << "Sorry, I found nothing.\n";
}
void solve(bool(*f)(const article&, const string&, const string&), const string& le, const string& ri) {
bool flag(false);
for (auto& r : dat) {//why it can't be "const auto& r"? because if a map is const,r.word[i] would be invalid
if (f(r, le, ri)) {
set<unsigned> re;
if (r.word.count(le)) for (const auto& rr : r.word[le]) re.insert(rr);
if (r.word.count(ri)) for (const auto& rr : r.word[ri]) re.insert(rr);
if (re.empty()) continue;
if (flag) cout << "----------\n";
else flag = true;
for (const auto& rr : re)
cout << r.line[rr] << '\n';
}
}
if (!flag) cout << "Sorry, I found nothing.\n";
}
int main()
{
//freopen("in.txt", "r", stdin);//
std::ios::sync_with_stdio(false);
cin >> N;
cin.ignore();//absorb '\n'
for (unsigned now(0);now < N;++now) { //read contexts of articles
int ln(0);//line number of current article
dat.push_back(tmpart);//create a empty article
while (getline(cin, tmpstr) && tmpstr != "**********") {
dat[now].line.push_back(tmpstr);
for (auto& r : tmpstr) {
if (r >= 'a'&&r <= 'z') continue;
if (r >= 'A'&&r <= 'Z') r += 32;
else r = ' ';
}
istringstream in(tmpstr);
while (in >> tmpstr)
dat[now].word[tmpstr].push_back(ln);
++ln;
}
}
cin >> M;
cin.ignore();
while (M--) { //read requests
string sl, sm, sr;//left middle right
getline(cin, tmpstr);
istringstream in(tmpstr);
in >> sl;
if (!(in >> sm)) solve(ONLY, sl, sl);
else if (!(in >> sr)) NOT(sm);//why are you so special
else if (sm[0] == 'A') solve(AND, sl, sr);
else solve(OR, sl, sr);
cout << "==========\n";
}
return 0;
}
[刷题]算法竞赛入门经典(第2版) 5-10/UVa1597 - Searching the Web的更多相关文章
- [刷题]算法竞赛入门经典(第2版) 4-6/UVa508 - Morse Mismatches
书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,10 ms) //UVa508 - Morse Mismatches #include< ...
- [刷题]算法竞赛入门经典(第2版) 5-15/UVa12333 - Revenge of Fibonacci
题意:在前100000个Fibonacci(以下简称F)数字里,能否在这100000个F里找出以某些数字作为开头的F.要求找出下标最小的.没找到输出-1. 代码:(Accepted,0.250s) / ...
- [刷题]算法竞赛入门经典(第2版) 5-13/UVa822 - Queue and A
题意:模拟客服MM,一共有N种话题,每个客服MM支持处理其中的i个(i < N),处理的话题还有优先级.为了简化流程方便出题,设每个话题都是每隔m分钟来咨询一次.现知道每个话题前来咨询的时间.间 ...
- [刷题]算法竞赛入门经典(第2版) 4-5/UVa1590 - IP Networks
书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,0 ms) //UVa1590 - IP Networks #include<iost ...
- [刷题]算法竞赛入门经典(第2版) 6-7/UVa804 - Petri Net Simulation
题意:模拟Petri网的执行.虽然没听说过Petri网,但是题目描述的很清晰. 代码:(Accepted,0.210s) //UVa804 - Petri Net Simulation //Accep ...
- [刷题]算法竞赛入门经典(第2版) 6-6/UVa12166 - Equilibrium Mobile
题意:二叉树代表使得平衡天平,修改最少值使之平衡. 代码:(Accepted,0.030s) //UVa12166 - Equilibrium Mobile //Accepted 0.030s //# ...
- [刷题]算法竞赛入门经典(第2版) 6-1/UVa673 6-2/UVa712 6-3/UVa536
这三题比较简单,只放代码了. 题目:6-1 UVa673 - Parentheses Balance //UVa673 - Parentheses Balance //Accepted 0.000s ...
- [刷题]算法竞赛入门经典(第2版) 5-16/UVa212 - Use of Hospital Facilities
题意:模拟患者做手术. 其条件为:医院有Nop个手术室.准备手术室要Mop分钟,另有Nre个恢复用的床.准备每张床要Mre分钟,早上Ts点整医院开张,从手术室手术完毕转移到回复床要Mtr分钟.现在医院 ...
- [刷题]算法竞赛入门经典(第2版) 5-11/UVa12504 - Updating a Dictionary
题意:对比新老字典的区别:内容多了.少了还是修改了. 代码:(Accepted,0.000s) //UVa12504 - Updating a Dictionary //#define _XieNao ...
随机推荐
- 一个web应用的诞生(9)--回到用户
在开始之前,我们首先根据之前的内容想象一个场景,用户张三在网上浏览,看到了这个轻博客,发现了感兴趣的内容,于是想要为大家分享一下心情,恩?发现需要注册,好,输入用户名,密码,邮箱,并上传头像后,就可以 ...
- Unity无缝循环世界实现
一年前曾经碰到过已无限世界为题材的游戏开发比赛,虽然对比赛没有兴趣,但是对这个题材倒是有点想法.如何通过unity3d实现无缝的循环世界呢. 有一种想法是动态生成,一块场景一块场景进行动态加载.(做过 ...
- 使用SevenZipSharp压缩/解压7z格式
7z格式采用的LZMA算法,号称具有现今最高压缩率.笔者在nuget上搜索7z,在搜索结果中最终选择了SevenZipSharp来进行压缩/解压.不得不说,SevenZipSharp的API设计得非常 ...
- SQLite 数据库
内容来源:高成珍.钟元生<Android编程经典案例解析> SQLite 数据库是Android 中内嵌的轻量级关系型数据库,本质上只是一个文件.SQLite 内部只支持NULL,INTE ...
- JS滚动加载
var one = true;//设置一个全局变量 $(window).scroll(function () { var hight = document.body.scrollHeight - do ...
- 浅谈css中单位px和em,rem的区别-转载
px是你屏幕设备物理上能显示出的最小的一个点,这个点不是固定宽度的,不同设备上点的长宽.比例有可能会不同.假设:你现在用的显示器上1px宽=1毫米,但我用的显示器1px宽=两毫米,那么你定义一个div ...
- 转账示例(四):service层面实现(线程管理Connection,AOP思想,动态代理)(本例采用QueryRunner来执行sql语句,数据源为C3P0)
用了AOP(面向切面编程),实现动态代理,service层面隐藏了开启事务.1.自行创建C3P0Uti,account数据库,导入Jar包 2.Dao层面 接口: package com.learni ...
- 【react学习】关于react框架使用的一些细节要点的思考
( _(:3 」∠)_给园友们提个建议,无论是API文档还是书籍,一定要多看几遍!特别是隔一段时间后,会有意想不到的收获的) 这篇文章主要是写关于学习react中的一些自己的思考: 1.set ...
- Yii2发送邮件
1.在配置文件main-local.php components=>[]里面配置 'mailer' => [ 'class' => 'yii\swiftmailer\Mailer', ...
- IOS 私有变量 私有属性的书写方法
一.早期只能定义在.h文件中.用@private 关键字来定义私有变量. @interface ViewController{ @private Bool _isBool; } @end 二.允许在. ...