2018计蒜客之道初赛

小明刚刚入职淘宝,老大给他交代了一个简单的任务,实现一个简易的商品推荐系统。

这个商品推荐系统的需求如下:

一共有 n 件商品可以被推荐,他们的编号分别为 1 到 n。每件商品都有一个价格,编号为 i 的商品价格为 pi​ 元。现在需要给用户推荐尽可能多的商品,但是要保证按照编号上升的顺序给用户依次推荐商品,并且,相邻商品的价格之差的绝对值不能超过 d。注意,第一个推荐的商品价格没有限制。

输入格式
第一行输入一个整数 T,表示测试数据组数。

接下来依次输入 T 组数据,每组数据按照下面的格式输入:

第一行输入两个整数 n 和 d,意义如题目描述所示。

接下来一行输入 n 个整数,第 i 个整数表示 pi​。

保证 ∑1< T≤50, 1≤n≤30000, 0≤d≤100, 1≤pi​≤105。

保证 ∑n≤6∗105。

输出格式
对于每组数据,输出一行一个整数,表示最多能推荐的商品个数。
样例输入
2
6 3
5 7 3 6 10 9
8 6
4 7 9 5 8 1 9 10
样例输出
4
7

题解:

用dp[i] 表示最后一个推荐商品的价格为i的最大数量,那么对于价格为p[i]的商品,能转移dp[p[i]的那么只有区间[dp[i]-d,dp[i]+d]所以暴力枚举转移就可以

代码:


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int p[maxn];
int res[maxn];//表示最后一个推荐的商品价格为i的最大数量dp[p[i]] 的区间为 [[p[i]-d,p[i]+d]
int dp[maxn];///代表第i件商品的 个数
int n,d,t,temp;

int main()
{
    int t;
    scanf("%d",&t);
    while(t --)
    {
        memset(dp,0,sizeof(dp));
        memset(res,0,sizeof(res));

        scanf("%d %d",&n,&d);

        for(int i = 1;i <= n;i ++) scanf("%d",&p[i]);

        for(int i = 1;i <= n;i ++)
        {

            temp = 0;
            ///遍历允许价钱的范围然后维护dp[i]
            for(int j = max(0,p[i] - d);j <= min(p[i]+d,100000);j ++)
            {
                temp = max(res[j],temp);
            }
            dp[i] = temp + 1;///到每个商品位置后的数量

            res[p[i]] = max(res[p[i]],dp[i]);///维护每个p【i】的最大值
        }

        int ans = 0;
        for(int i = 1;i <=n;i ++)
            ans = max(ans,dp[i]);
        //printf("%d\n",dp[i]);
        printf("%d\n",ans);
    }

    return 0;
}

阿里巴巴的手机代理商正在研究 infra 输入法的新功能。他们需要分析单词频率以改进用户输入法的体验。于是需要你在系统内核里面写一个 API。 API 有如下功能:

添加操作

添加操作格式为insert barty 8,意思为插入barty这个单词,这个单词词频为 88 次。注意如果再次添加insert barty 8操作时,就会将词频增加为 1616 次。(不会出现词频 \le 0≤0 的情况)。

删除操作

删除操作格式为delete barty,意思为删除所有barty这个单词。

如果当前没有删除的词汇,输出Empty。

查询操作

查询操作格式为query ty,意思为查询当前版本以ty结尾的单词词频总和。

输入格式
第一行读入一个整数 TT,代表数据组数。

每组数据的第一行读入一个整数 NN 代表操作数。

接下来 NN 行,每行形容一个操作。

保证数据满足 1 \le T \le 101≤T≤10,1 \le N \le 10001≤N≤1000,insert操作的字符串总长度之和 \le 3000≤3000,所有字符串长度 \le 10000≤10000,输入只有小写字母。

输出格式
输出题目中要求的结果。

样例输入
1
6
insert barty 8
query ty
insert party 9
query ty
delete barty
query ty
样例输出
8
17
9
题解 :
直接拿map模拟用来维护插入,如果删除直接将map的第2维转化为0,截断字符串。
代码如下:

#include<bits/stdc++.h>
using namespace std;

string s1,s2,s3;
map<string,int>mp;
map<string,int>::iterator it;
int main()
{ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n,t,xx;
    cin >> t;
    string s1,s2;

    while(t --)
    {

        mp.clear();
        cin >> n;
        for(int i = 0; i < n; i ++)
        {
            cin >> s1;
            if(s1 == "insert")
            {
                cin >> s2 >> xx;
                mp[s2] += xx;
            }
            else if(s1 == "query")
            {
                cin >> s2;
                int ans =0;

                int len1 = s2.size();
                int cnt = 0;
                for(it = mp.begin(); it != mp.end(); it ++)
                {
                    int len = it -> first.size();
                    s3 = "";
                    if(len >= len1)
                        s3 = (it->first).substr(len - len1,len);
                    if(s3 == s2)
                        ans += it->second;
                }
                cout << ans << endl;


            }
            else if(s1 == "delete")
            {
                cin >> s2;
                if(mp[s2] == 0)
                    cout << "Empty" << endl;
                else
                    mp[s2] = 0;

            }

        }
    }
    return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值