zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:字符交换(贪心+模拟)

    题目传送门(内部题136)


    输入格式

      输入文件第一行为两个正整数$n,k$,第二行为一个长度为$n$的小写字母字符串$s$。


    输出格式

      输出一个整数,为对字符串$s$进行至多$k$次交换相邻字符的操作后,字符串$s$可能达到的最大的$m$指标。


    样例

    样例输入:

    6 3
    abacba

    样例输出:

    3


    数据范围与提示

      对于$40\%$的数据,满足$nleqslant 10$。
      对于$70\%$的数据,满足$nleqslant 200$。
      对于$100\%$的数据,满足$1leqslant nleqslant 4,000,1leqslant kleqslant n^2$。


    题解

    如果最终连续,那么一定有至少一个字符不动。

    于是可以枚举字符,然后将同种字符最小的挪向它即可,用小根堆维护就好了。

    其实因为答案满足单调性,所以可以用二分优化。

    时间复杂度:$Theta(n^2)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    int N,K;
    char ch[4001];
    int a[4001];
    vector<int> pos[30];
    int ans;
    int main()
    {
    	scanf("%d%d",&N,&K);
    	scanf("%s",ch+1);
    	for(int i=1;i<=N;i++)
    	{
    		a[i]=ch[i]-'a'+1;
    		pos[a[i]].push_back(i);
    	}
    	for(int i=1;i<=26;i++)
    	{
    		for(int j=0;j<pos[i].size();j++)
    		{
    			int L=(j==0)?1:pos[i][j-1]+(pos[i][j]-pos[i][j-1]+1)/2;
    			int R=(j==pos[i].size()-1)?N:pos[i][j+1]-(pos[i][j+1]-pos[i][j]+1)/2;
    			for(int k=L;k<=R;k++)
    			{
    				int cnt=1;
    				int sum=abs(pos[i][j]-k);
    				if(sum>K)continue;
    				priority_queue<int,vector<int>,greater<int> > q;
    				for(int l=0;l<pos[i].size();l++)
    				{
    					if(l<j)q.push(k-pos[i][l]-j+l);
    					if(l>j)q.push(pos[i][l]-k-l+j);
    				}
    				while(q.size()&&sum+q.top()<=K)
    				{
    					cnt++;
    					sum+=q.top();
    					q.pop();
    				}
    				ans=max(ans,cnt);
    			}
    		}
    	}
    	printf("%d",ans);
    	return 0;
    }
    

    rp++

  • 相关阅读:
    Alpha冲刺(4/6)
    Alpha冲刺(3/6)
    Alpha冲刺(2/6)
    Alpha冲刺(1/6)
    团队Git现场编程实战
    团队项目-需求分析报告
    团队项目-选题报告
    第二次结对编程作业
    第一次团队展示
    第一次结对编程作业
  • 原文地址:https://www.cnblogs.com/wzc521/p/11830027.html
Copyright © 2011-2022 走看看