UVA ~ 11991 ~ Easy Problem from Rujia Liu? (map + vector)

题意:给出一个包含n 个整数的数组,你需要回答若干询问。每次询问两个整数k和v,输出从左到右第k个V的下标(数组下标从左到右编号为1~n)。

[输入格式]

    输入包含多组数据。每组数据第一行为两个整数n 和m (1<=n,m<=100000),第二行包含n个不超过10^6的正整数,即待查询的数组。以下m行每行包含两个整数k和V (1<=k<=n,I<=v<=10^6)。输入结束标志为文件结束符(EOF)。输入文件不超过5MB。[输出格式)

  对于每个查询,输出查询结果。如果不存在,输出0。

[分析]

    本题有很多做法,下面描述一种编程复杂度小,时间效率也满足题目要求的方法。从查询的角度讲,如果能把输入组织成一个可以“直接读结果”的数据结构,是最好不过了。比如,如果data[v][k]就是答案,那该有多好!

  事实上,这样的数据结构是存在的。首先,因为v的范围很大,这里的data不应该是个数组,而是一个STL 的map。也就是说,data[v]是指在data 这个map 中键v所对应的“值”。由于我们还要以data[v][k]这样的方式访问,data[v]的“值”应当是一个数组,保存整数v从左到右依次出现的下标(因此第k 次出现的下标就是data[v][k])。 由于不同整数出现的次数可以相差很大,data[v]不应是一一个定长数组,否则会有大量的空间浪费。换句话说,data[V]应该是一个变长数组,如vector<int>

    这样,我们就可以利用vector 和map 这两个现成的数据结构简洁地解决本题,代码如下。


#include<bits/stdc++.h>
using namespace std;
int n, m;
map<int, vector<int> > mp;
int main()
{
    while (~scanf("%d%d", &n, &m))
    {
        mp.clear();
        for (int i = 1; i <= n; i++)
        {
            int x; scanf("%d", &x);
            if (!mp.count(x)) mp[x] = vector<int>();
            mp[x].push_back(i);
        }
        while (m--)
        {
            int k, v; scanf("%d%d", &k, &v);
            if (!mp.count(v) || mp[v].size() < k) printf("0\n");
            else printf("%d\n", mp[v][k-1]);
        }
    }
    return 0;
}
/*
8 4
1 3 2 2 4 3 2 1
1 3
2 4
3 2
4 2
*/

自己一开始想到的方法:

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
int n, m;
map<int, int> vis;
map<pair<int, int>, int> mp;
int main()
{
    while (~scanf("%d%d", &n, &m))
    {
        vis.clear(); mp.clear();
        for (int i = 1; i <= n; i++)
        {
            int v; scanf("%d", &v);
            if (vis.count(v)) vis[v]++;
            else vis[v] = 1;
            mp.insert(make_pair(make_pair(vis[v], v), i));
        }
        while (m--)
        {
            int k, v; scanf("%d%d", &k, &v);
            printf("%d\n", mp[make_pair(k, v)]);
        }
    }
    return 0;
}
/*
8 4
1 3 2 2 4 3 2 1
1 3
2 4
3 2
4 2
*/


请帮我写一份c++代码,解决一下问题,要求符合输入输出本There are n people (excluding myself) in my 30th birthday party. They sing the traditional “happy birthday” song: Happy birthday to you! Happy birthday to you! Happy birthday to Rujia! Happy birthday to you!!! Since I love music, I want to hear something more interesting, not that everyone sings together. Ah yes, I want one person to sing one word! For example, there are three people: Mom, Dad, Girlfriend, I’d like them to sing like this: Mom: Happy Dad: birthday Girlfriend: to Mom: you Dad: Happy Girlfriend: birthday Mom: to Dad: you Girlfriend: Happy Mom: birthday Dad: to Girlfriend: Rujia Mom: Happy Dad: birthday Girlfriend: to Mom: you Very nice, right? What if there are more than 16 people? That’s easy: repeat the song until everyone has sung at least once :) Please, don’t stop in the middle of the song.Input There is only one test case. The first line contains a single integer n (1 ≤ n ≤ 100). Then each of the next n lines contains a capitalized name (i.e. one upper-case letter followed by zero or more lowercase letters). Each name contains at most 100 characters and do not have whitespace characters inside. Output Output the song, formatted as above. Sample Input 3 Mom Dad Girlfriend Sample Output Mom: Happy Dad: birthday Girlfriend: to Mom: you Dad: Happy Girlfriend: birthday Mom: to Dad: you Girlfriend: Happy Mom: birthday Dad: to Girlfriend: Rujia Mom: Happy Dad: birthday Girlfriend: to Mom: you
最新发布
12-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值