- 当在天猫购物,使用关键词搜索商品时,可以选择很多附选条件,比如品牌,价格等,之后会出现符合当前条件的商品及数量,如图,搜索词为:羽绒服,附选条件为:价格¥500-¥1000
- 主页陈列出符合条件的商品,以及一个商品数量(见右上角),但商品数量会因为商家上架、下架商品而改变,因此买家在不同时间段搜索商品时,显示的数量会不一样。
- 接下来包含一个含有多行的文本文件,文件的每行代表上架,下架,查询三种行为的一种,本题默认查询对象是‘衣服’。
- 请计算所有买家查询结果的总和。
- 举例: 一个拥有6行的文件。
- up 3 11 (有一个商家上架了3件11rmb的衣服。)
- query 11 25 (有一个买家查询11rmb-25rmb的衣服的数量。这里的查询结果是:3件)
- up 5 25 (有一个商家上架了5件25rmb的衣服。)
- query 11 25 (有一个买家查询11rmb-25rmb的衣服的数量。这里的查询结果是:8件)
- down 3 25 (有一个商家下架了3件25rmb的衣服。)
- query 20 25 (有一个买家查询20rmb-25rmb的衣服的数量。这里的查询结果是:2件)
- 这题的答案是所有买家查询结果的总和为13(3+8+2=13)。
题目2:- 本题与‘商品数量-1’题型一致,仅改变文本文件。
- 请下载本题文本文件,计算所有买家查询结果的总和。
- 举例: 一个拥有6行的文件。
-
题目2就是加大了数量,不过下面代码都是可以计算出来的。
-
#include <iostream> #include <cstdio> #include<ctime> using namespace std; int num[111111]; int main() { freopen("f:/demo//144043063958496.txt","r",stdin); char s[8]; clock_t start,finish; start=clock(); int t1,t2; long long ans=0; while(scanf("%s%d%d",s,&t1,&t2)!=EOF){ if(s[0]=='u'){ num[t2]+=t1; }else if(s[0]=='d'){ num[t2]-=t1; }else{ for(int i=t1;i<=t2;i++) ans+=num[i]; } } finish=clock(); printf("%lld\n",ans); cout << finish-start << "/" << CLOCKS_PER_SEC << " (s) "<< endl; return 0; }
我还特别加了个时间函数看它跑十万的数据需要多久,运行结果如下: -
3.7秒,在ACM题中肯定是超时的,于是我就用线段树来做了一遍。
-
可以看到速度的巨大的提升:#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<ctime> #include<iostream> using namespace std; typedef struct{ int left,right; int val; } node; node tree[100001*4]; void build (int node,int left,int right) { tree[node].left=left; tree[node].right=right; tree[node].val=0; if(left==right) return ; int mid=(left+right)>>1; build(node*2,left,mid); build(node*2+1,mid+1,right); } void update(int node,int pos,int val) { if(tree[node].left==pos&&tree[node].right==pos){ tree[node].val+=val; return; } int mid=(tree[node].left+tree[node].right)>>1; if(pos<=mid) update(node*2,pos,val); else if(pos>mid) update(node*2+1,pos,val); tree[node].val=tree[node*2].val+tree[node*2+1].val; } int query(int node,int left,int right) { if (tree[node].left == left && tree[node].right == right) return tree[node].val; if (tree[node].left > right || tree[node].right < left) return 0; int mid; mid=(tree[node].left + tree[node].right)>>1; if (right <= mid) return query(node * 2, left, right) ; else if (mid < left) return query(node * 2 + 1, left, right) ; else return query(node * 2, left, mid)+query(node * 2 + 1, mid + 1, right) ; } int main() { freopen("f:/demo//144043063958496.txt","r",stdin); char s[8]; clock_t start,finish; start=clock(); int t1,t2; long long ans=0; int n=100000; build(1,1,n); while(scanf("%s%d%d",s,&t1,&t2)!=EOF){ if(s[0]=='u'){ update(1,t2,t1); }else if(s[0]=='d'){ update(1,t2,-t1); }else{ ans+=query(1,t1,t2); } } finish=clock(); printf("%lld\n",ans); cout << finish-start << "/" << CLOCKS_PER_SEC << " (s) "<< endl; return 0; }
-
-
-
看到这个结果时,真的感觉莫名的开心啊,这就是算法的乐趣所在吧.
-
-