随笔- 19  文章- 0  评论- 0  阅读- 838 

D-字符串里串

题目链接

题目描述🥰

题目思路😀

这道题是个比较简单的思维题,根据题目定义,我们需要求得字符串的最大可爱度,只需要满足一个条件:那就是有字符串a的前面有字符串a的开头字母,那样就可以构成字符串b了,或者字符串的后面有字符串a的末尾元素,如样例里面的abcc,在字符串abc的后面又有末尾元素c,所以最大可爱度就是3

所以解题步骤:

  1. 我们首先考虑在字符串a的前面有字符串a的开头字母的情况,从头开始遍历数组,用一个哈希表来记录前面的元素,如果一个元素已经出现了,所以后面的字符串就可以当成字符串a,因为越到后面,字符串a的长度肯定越来越小,所以第一次找到合适的字符串,我们直接记录答案,break即可。
  2. 其次我们可以考虑字符串的后面有字符串a的末尾元素,原理和前面是一样的,就不一一阐述了。如果要重复利用之前的哈希表,前面的哈希表要记得清空
  3. 最值得注意的是:题目提及不连续子序列定义为至少由两段不相邻的非空子串构成,所以我们需要对可爱度为1的进行特判,输出0。

AC代码🧠

// Problem: 字符串里串
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/95334/D
// Memory Limit: 2048 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

#define dev1(a) cout << #a << '=' << a << endl;
#define dev2(a, b) cout << #a << " = " << a << "  " << #b << " = " << b << endl;
#define dev3(a, b, c) cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " << c << endl;
#define dev4(a, b, c, d) cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " << c << "  " << #d << " = " << d << endl;
#define dev5(a, b, c, d, e) cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " << c << "  " << #d << " = " << d << "  " << #e << " = " << e << endl;
#define vec(a)                         \
    for (int i = 0; i < a.size(); i++) \
        cout << a[i] << ' ';           \
    cout << endl;
#define darr(a, _i, _n)               \
    cout << #a << ':';                \
    for (int ij = _i; ij <= _n; ij++) \
        cout << a[ij] << ' ';         \
    cout << endl;           
#define cin(a,n)           \
     for(int i=0;i<n;i++) \
      cin>>a[i];          
#define endl "\n"
#define pow pim
int pim(int a,int k)
{
    int res=1;
    if(a==0)return 0;
    while(k) 
    {
        if(k&1)res=(int)res*a;
        k>>=1;
        a=(int)a*a;
    }
    return res;
}
#define fi first
#define se second
#define caseT \
    int T;    \
    cin >> T; \
    while (T--)
// #define int long long
// #define int __int128

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 99999999;

// const int N = ;
int gcd(int a, int b)
{
    return b ? gcd(b, a % b) : a;
}
 
int lcm(int a, int b)
{
    return a * b / gcd(a, b);
}
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
void solve()
{
	int n;
	cin>>n;
	string s;
	cin>>s;
	//要么是最后一个元素重复,要么是第一个元素重复
	map<char,int>hash;
	int ans=0;
	for(int i=0;i<n;i++)
	{
		if(hash[s[i]])
		{
			ans=max(ans,n-i);
			break;
		}
		hash[s[i]]++;
	}
	hash.clear();
	for(int i=n-1;i>=0;i--)
	{
		if(hash[s[i]])
		{
			ans=max(ans,i+1);
			break;
		}
	}
	if(ans==1)cout<<0<<endl;
	else cout<<ans<<endl;
}

signed main()
{

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	// caseT
    solve();
    return 0;
}
/*

*/

一起走很长的路!

题目链接

题目描述🥰

题目思路😀

这个题目就是典型的考查线段树或者st表的题目,我们的调整次数可以全加在第l个板子上面,这样可以保证对全局是有利的。

其次我们需要计算的是在l+1到r这个区间里面的i的(presum[i-1]-presum[l-1]-a[i])的最小值,对于这个求区间里面的最大值问题,无疑是采用st表或是线段树数据结构,在这个题我用的是st表。

所以解题步骤是:

  1. 首先预处理一个前缀和数组presum
  2. 再预处理一个存每一个presum[i-1]-a[i]的数组,用这个数组来构造st表,来处理后面的请求
  3. 对于每一次的请求,我们只要输出abs(min(0LL,st.askmin(l+1,r)-presum[l-1]))(因为如果要调整,那么st.askmin(l+1,r)-presum[l-1]一定是负数,所以要取的min,而不是max)
  4. 注意我们需要对l==r的情况进行特判,这种情况肯定是不需要调整的

AC代码🧠

// Problem: 一起走很长的路!
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/95334/E
// Memory Limit: 2048 MB
// Time Limit: 4000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

#define dev1(a) cout << #a << '=' << a << endl;
#define dev2(a, b) cout << #a << " = " << a << "  " << #b << " = " << b << endl;
#define dev3(a, b, c) cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " << c << endl;
#define dev4(a, b, c, d) cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " << c << "  " << #d << " = " << d << endl;
#define dev5(a, b, c, d, e) cout << #a << " = " << a << "  " << #b << " = " << b << "  " << #c << " = " << c << "  " << #d << " = " << d << "  " << #e << " = " << e << endl;
#define vec(a)                         \
    for (int i = 0; i < a.size(); i++) \
        cout << a[i] << ' ';           \
    cout << endl;
#define darr(a, _i, _n)               \
    cout << #a << ':';                \
    for (int ij = _i; ij <= _n; ij++) \
        cout << a[ij] << ' ';         \
    cout << endl;           
#define cin(a,n)           \
     for(int i=0;i<n;i++) \
      cin>>a[i];          
#define endl "\n"
#define pow pim
int pim(int a,int k)
{
    int res=1;
    if(a==0)return 0;
    while(k) 
    {
        if(k&1)res=(int)res*a;
        k>>=1;
        a=(int)a*a;
    }
    return res;
}
#define fi first
#define se second
#define caseT \
    int T;    \
    cin >> T; \
    while (T--)
#define int long long
// #define int __int128

using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;

const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 99999999;

const int N = 2e5+10;
int gcd(int a, int b)
{
    return b ? gcd(b, a % b) : a;
}
 
int lcm(int a, int b)
{
    return a * b / gcd(a, b);
}
template<typename T>
struct RMQ {
  int n;
  vector<T>a;
  RMQ(vector<T>_a,int _n):a(_a),n(_n){
    stmin.resize(n + 5);
    for (int i = 0; i <= n; i++) {
      stmin[i].resize(21, 0);
    }
    solve();
  }
  vector<vector<T>> stmin;
  void solve() {
    for (int i = 1; i <= n; i++) {
      stmin[i][0] = a[i];
    }
    for (int i = 1; (1 << i) <= n; i++) {
      int len = (1 << i);
      for (int j = 1; j + len - 1 <= n; j++) {
        stmin[j][i] = min(stmin[j][i - 1], stmin[j + (1 << (i - 1))][i - 1]);
      }
    }
  }
  T askmin(int l, int r) {
    int len = log2(r - l + 1);
    return min(stmin[l][len],stmin[r - (1 << len) + 1][len]);
  }
  
};
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

signed main()
{

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	// caseT
	int n,q;
	cin>>n>>q;
	vector<int>a(n+1);
	for(int i=1;i<=n;i++)cin>>a[i];
	//我要求的是在l+1到r这个区间里面的i的(presum[i-1]-presum[l-1]-a[i])的最小值
	vector<int>presum(n+1);
	for(int i=1;i<=n;i++)presum[i]=presum[i-1]+a[i];
	vector<int>exisum(n+1);
    // exisum算的是presum[i]-a[i]
	for(int i=1;i<=n;i++)exisum[i]=presum[i-1]-a[i];
	RMQ st(exisum,n);
	while(q--)
	{
	     int l,r;
	     cin>>l>>r;
	     if(l==r)
	     {
	     	cout<<0<<endl;
	     	continue;
	     }
	     int k=presum[l-1];
	     cout<<abs(min(0LL,st.askmin(l+1,r)-k))<<endl;
	}
    return 0;
}
/*

*/

 

 posted on   熙玺  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

Shu-How Zの小窝

Loading...
点击右上角即可分享
微信分享提示