离散化的三种方法(转载)
题意:
n棵树依次排好,每棵树都有一个高度,树的顶端有一只鸟。
猎人会打M枪,每一枪都能从高度为X的树上打下一只鸟,问每一枪打下的鸟是从 编号多少的树 上掉下来的
题解思路:
因为树的高度能达到(10^9) 而树的数量最多10^5 所以离散化 将所有高度为X的树离散化为 高度为第X高的树
有多种方法。
1 stl去重+set版:
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<set>
- #include<algorithm>
- #define MAXN 100050
- using namespace std;
- int h[MAXN];
- int q[MAXN];
- int s[MAXN*2];
- set<int>ans[MAXN*2];
- int main()
- {
- int n,m,cnt;
- while(~scanf("%d%d",&n,&m))
- {
- cnt=0;
- for(int i=0;i<n;i++)
- {
- scanf("%d",&h[i]);
- s[cnt++]=h[i];
- }
- for(int j=0;j<m;j++)
- {
- scanf("%d",&q[j]);
- s[cnt++]=q[j];
- }
- sort(s,s+cnt);
- cnt=unique(s,s+cnt)-s;
- for(int i=0;i<cnt;i++)
- ans[i].clear();
- for(int i=0;i<n;i++)
- {
- int d=lower_bound(s,s+cnt,h[i])-s;
- ans[d].insert(i+1);
- }
- for(int j=0;j<m;j++)
- {
- int d=lower_bound(s,s+cnt,q[j])-s;
- if(ans[d].empty())
- printf("-1\n");
- else
- {
- printf("%d\n",*ans[d].begin());
- ans[d].erase(ans[d].begin());
- }
- }
- }
- return 0;
- }
土方法离散:
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<vector>
- using namespace std;
- #define maxn 100010
- struct H
- {
- int v,id;
- }num[2*maxn];
- int w[2*maxn];
- int vis[maxn<<1];
- bool cmp(H a,H b)
- {
- return a.v<b.v;
- }
- vector <int> vc[maxn<<1];
- int main()
- {
- int n,m;
- int cnt;
- while(~scanf("%d%d",&n,&m)){
- cnt=0;
- for(int i=0;i<n;i++)
- {
- int xx;
- scanf("%d",&xx);
- num[i].v=xx;num[i].id=i;
- }
- for(int i=n;i<n+m;i++)
- {
- int xx;scanf("%d",&xx);
- num[i].v=xx;num[i].id=i;
- }
- sort(num,num+n+m,cmp);
- int tot=0;w[num[0].id]=0;
- for(int i=1;i<n+m;i++)
- {
- if(num[i].v==num[i-1].v){
- w[num[i].id]=tot;
- }
- else w[num[i].id]=++tot;
- }
- memset(vis,0,sizeof(vis));
- for(int i=0;i<n;i++)
- {
- vis[w[i]]++;vc[w[i]].push_back(i+1);
- }
- for(int i=n;i<n+m;i++)
- {
- if(vis[w[i]]>0)
- {
- int le=vc[w[i]].size()-vis[w[i]];
- printf("%d\n",vc[w[i]][le]);
- vis[w[i]]--;
- }
- else printf("-1\n");
- }
- }
- return 0;
- }
set+map:
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <iostream>
- #include <vector>
- #include <map>
- #include <set>
- #include <queue>
- #include <algorithm>
- #define read freopen("q.in","r",stdin)
- #define LL long long
- #define maxn 100005
- using namespace std;
- set<int> mp[maxn];
- map<int,int> c;
- //http://www.2cto.com/kf/201108/100912.html
- //http://blog.csdn.net/tyzhaoqi2004/article/details/6882660
- int main()
- {
- //read;
- int n,m;
- while(scanf("%d%d",&n,&m)!=EOF)
- {
- int i,j,q,x,t=0;
- for(i=1;i<=n;i++)
- mp[i].clear();
- c.clear();
- for(i=0;i<n;i++)
- {
- scanf("%d",&x);
- if(!c[x])c[x]=++t;
- mp[c[x]].insert(i+1);
- // cout<<c[x]<<" ";
- }
- //for(i=1;i<=t;i++)cout<<c[i]<<" ";
- // cout<<endl;
- for(i=0;i<m;i++)
- {
- scanf("%d",&q);
- if(mp[c[q]].size()==0)
- {
- printf("-1\n");
- }
- else
- {
- // cout<<mp[q].size()<<" %% "<<endl;
- printf("%d\n",*(mp[c[q]].begin()));
- mp[c[q]].erase(mp[c[q]].begin());
- // cout<<mp[q].size()<<" %% "<<endl;
- }
- }
- }
- }