Codeforces Round #624 (Div. 3)C. Perform the Combo

℡╲_俬逩灬. 提交于 2020-02-25 23:26:22

C. Perform the Combo

题目链接-C. Perform the Combo
在这里插入图片描述
在这里插入图片描述

题目大意

给出一个仅由小写字母组成的字符串,再给出一个序列p[]代表在哪些地方按键会出错,每次出错后需要从头开始重新遍历,问所有字母最后分别被按过多少次

解题思路

  • 思路1
    前缀和+暴力做法,感觉不太好,运行时间太长了
  • 先用一个数组sum[]读取整个p[]数组,存下每个位置结尾的次数
  • 如果一个位置出了错误 那么这个位置前面所有的字母都需要重复一次
  • 最后直接把出现错误的加上就行了
    在这里插入图片描述
    主要讲一下fill()函数memset()函数
  • 因为memset()函数按照字节填充,所以一般memset()只能用来填充char型数组,(因为只有char型占一个字节),如果填充int型数组,只能填充0 -1和INF(正负都行),memset(arr, val, sizeof arr);
  • 而fill()函数可以赋值任何值,比如int数组:fill(arr, arr+n,val);vector也可以:fill(v.begin(), v.end(), val);
  • memset()函数在头文件<cstring>里,fill()函数在头文件<algorithm>

注意:不能在没有元素的空容器上调用fill_n()函数

附上代码

#include<bits/stdc++.h>
#define int long long
#define lowbit(x) (x &(-x))
using namespace std;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-10;
const int M=1e9+7;
const int N=2e5+5;
typedef long long ll;
typedef pair<int,int> PII;
int sum[N];
int ans[110];
string s;
signed main() {
    std::ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    
    int t;
    cin>>t;
    while(t--){
    	int n,m;
        cin>>n>>m;
        cin>>s;
        fill(ans,ans+100,0);
        fill(sum,sum+N,0);
        for(int i=0;i<m;i++){
        	int temp;
            cin>>temp;   
            sum[0]++;
            sum[temp]--;
        }
        int num=0;
        for(int i=0;i<n;i++){
            num+=sum[i];//前缀和
            ans[s[i]-'a']+=num;
            ans[s[i]-'a']++;
        }   
        for (int i=0;i<26;i++)
            cout<<ans[i]<<" ";
        cout<<endl;
    }
    return 0;
}
  • 思路2
    二分
  • 先把操作排序,通过lower_bound()函数找到第一个大于 i
    的位置k,m-k得到的就是这个位置因为打错而出现的次数,对应的字符加上这个数就行
  • lower_bound函数返回的是一个地址,如果要得到位置k需要把它减去首地址,这样就可以找到在数组第某项到第某项过程中的第一个大于某个数的数
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
char s[N];
int p[N],ans[26];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    
    int t;
	cin>>t;
	while(t--){
		int n,m;
		cin>>n>>m;
		cin>>s+1;
		memset(ans,0,sizeof ans);
		for(int i=0;i<m;i++)
			cin>>p[i];
		sort(p,p+m);
		for(int i=1;i<=n;i++){
			ans[s[i]-'a']++;
			int k=lower_bound(p,p+m,i)-p;
			ans[s[i]-'a']+=m-k;
		}
		for(int i=0;i<26;i++)
			cout<<ans[i]<<" ";
		cout<<endl;
	}
    return 0;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!