2018 Benelux Algorithm Programming Contest (BAPC 18) G-Game Night(滾動)
阿新 • • 發佈:2018-12-03
題意
給一個只含ABC的字串,
要求把字串的A放在一起B放在一起C放在一起,
問最少有多少個字母需要被移動位置。
思路來源
翼神
題解
就是一波暴力啊,和秦皇島那個字串暴力題很像。
全排列ABC、ACB、BCA、BAC、CAB、CBA六種,
考慮是圓串,所以可簡化為ABC、ACB兩種,
預處理兩個串,然後與原串暴力匹配即可,
原串也是圓串,所以將其重複一遍展成線性串。
統計一次的不同個數是O(n),然後用到滾動技巧。
這其實和滾動雜湊那裡線性求值差不多QAQ,也不知道是不是尺取。
A、B、C三部分向前滾動,l++,r++,修改下標更改時的值。
具體看程式碼吧,寫的很醜.jpg
程式碼
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cmath> #include <set> #include <map> #include <vector> #include <stack> #include <queue> #include <functional> const int INF=0x3f3f3f3f; const int maxn=1e5+10; const int mod=1e9+7; const int MOD=998244353; const double eps=1e-7; typedef long long ll; #define vi vector<int> #define si set<int> #define pii pair<int,int> #define pi acos(-1.0) #define pb push_back #define mp make_pair #define lowbit(x) (x&(-x)) #define sci(x) scanf("%d",&(x)) #define scll(x) scanf("%lld",&(x)) #define sclf(x) scanf("%lf",&(x)) #define pri(x) printf("%d",(x)) #define rep(i,j,k) for(int i=j;i<=k;++i) #define per(i,j,k) for(int i=j;i>=k;--i) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; int n,a,b,c,len; string s,t,u,v,Q[3]; int check(string a,string b) { int num=0,len=a.size(); rep(i,0,len-1)if(a[i]!=b[i])num++; return num; } int solve() { int ans=INF; rep(i,0,a-1)Q[0]+='A'; rep(i,0,b-1)Q[1]+='B'; rep(i,0,c-1)Q[2]+='C'; string s1="",s2=""; s1+=Q[0],s1+=Q[1],s1+=Q[2]; s2+=Q[0],s2+=Q[2],s2+=Q[1]; int ini1=check(s1,t),tmp1=ini1; rep(i,1,len-1) { if(s[i-1]=='A')tmp1++; if(s[i-1+a]=='A')tmp1--; if(s[i-1+a]=='B')tmp1++; if(s[i-1+a+b]=='B')tmp1--; if(s[i-1+a+b]=='C')tmp1++; if(s[i-1+a+b+c]=='C')tmp1--; ini1=min(ini1,tmp1); //printf("%d:%d\n",i,tmp1); } int ini2=check(s2,t),tmp2=ini2; rep(i,1,len-1) { if(s[i-1]=='A')tmp2++; if(s[i-1+a]=='A')tmp2--; if(s[i-1+a]=='C')tmp2++; if(s[i-1+a+c]=='C')tmp2--; if(s[i-1+a+c]=='B')tmp2++; if(s[i-1+a+b+c]=='B')tmp2--; ini2=min(ini2,tmp2); } ans=min(ans,ini1); ans=min(ans,ini2); return ans; } //ABC ACB int main() { sci(n); cin>>s; len=s.size(); rep(i,0,len-1) { if(s[i]=='A')a++; else if(s[i]=='B')b++; else c++; } t=s;s+=t; printf("%d\n",solve()); return 0; }