2024码蹄杯高职组初赛第二场 i题 数组搜索 题型:思维 难度:白银

77 阅读1分钟

码题集OJ-数组搜索 (matiji.net)

我刚开始是用的string的find()函数,但是find()的复杂度是O(n).这道题的数据范围是1e5,按照我的写法复杂度是O(n*m)的,会超:

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

signed main()
{
	int n, m; cin >> n >> m;
	getchar();

	//cout<<n<<m<<endl;
	string str; getline(cin, str);


	string s;
	for (int i = 0; i < str.size(); i++)
		if (str[i] != ' ')s += str[i];

	string s2 = s;
	reverse(s2.begin(), s2.end());
	//cout<<m<<endl;

    
	for (int i = 0; i < m; i++)
	{
		int t = 0;
		char op; char k; cin >> op >> k;

		if (op == 'L')
		{
			t = s.find(k);
		}
		else
		{
			t = s2.find(k);
			t = n-t- 1;
		}

		if (t < n&& t>=0) cout << t << endl;
		else cout << "-1" << endl;

	}
	return 0;
}

image.png

正解

用一个左map,一个右map来存储,这样遍历的时候2个map只需要O(2logn)的复杂度

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int mpl[N], mpr[N];
int x;
int main()
{
    int n, m; cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
       cin >> x;
        if (!mpl[x])
        {
            mpl[x] =mpr[x]= i;
        }
        else
        {
            mpr[x] = i;
        }
    }

    while (m--)
    {
        char op;cin >> op >> x;

        if (op == 'L')
        {
            if (mpl[x] == 0)
            {
                cout << "-1" << endl;
            }
            else cout << mpl[x] - 1<<endl;
        }
        else
        {
            if (mpr[x] == 0)cout << "-1" << endl;
            else cout << mpr[x] - 1 << endl;
        }
    }
    return 0;
}

image.png