2018 ICPC 南京 E. Eva and Euro coins(思維+棧)
阿新 • • 發佈:2021-02-01
技術標籤:演算法練習2021寒假區域賽真題ICPC區域賽補題
2018 ICPC 南京 全文見:https://blog.csdn.net/qq_43461168/article/details/112796538
E. Eva and Euro coins
題意:給定一排硬幣。也就是一個01串。要變成目標01串。限制是每次只能翻動連續的k個硬幣。
思路:這場榜是不是被帶偏了。E題應該是前期題呀。簡單思維+棧。觀察一下就可以發現,對於連續的k個相同的硬幣。如果存在的話。那目標串裡面也必然存在連續相同的才行。 其次,更重要的是,這連續的k個相同的,可以直接刪掉!為什麼呢。考慮這樣一個串 0101000101,k = 3,這時候只有中間有連續的3對吧。把他變成1,0101111101,然後左邊3個1變成0,0100001101,發現什麼。左邊的那個1,移動了三個0的右邊。 還可以接著移動。0111101101,0000101101,0000101101,三個0,移動到了整個串的最前面。其實不只是最前面。它可以移動到任意一個位置。而其他的字元相對位置不會改變。所以這3個零直接刪掉。是不影響最後結果的。因為如果 目標串也有3個0或者1。那麼也把他們刪掉就行了。除了可以移動連續的值外。其他的值。根本不會變。也就是說。只要把這些東西刪完。剩下的一樣就是一樣,不一樣就是不一樣,直接判就好了。 因為移動會使得原本不相連的串變得相連。那就涉及到棧了。這就和連連看一樣了。不斷的消去就行了。判斷最後剩下的串就行。
AC程式碼:
#include <iostream>
#include <bits/stdc++.h>
#include <unordered_map>
#define int long long
#define mk make_pair
#define gcd __gcd
using namespace std;
const double eps = 1e-10;
const int mod = 998244353;
const int N = 5e6+7;
int n,m,k,t = 1,cas = 1;
int a[N],b[N],c[N];
int mark[ N];
string s1,s2;
string ss1,ss2;
stack<pair<char,int> > st;
string get_tag(string s){
for(int i = 0 ; i < n ; i ++){
if(st.empty()){
st.push({s[i],1});
}else{
pair<char,int> tmp = st.top();
if(tmp.first == s[i]){
st. top().second ++;
}else{
st.push({s[i],1});
}
if(st.top().second == k){
st.pop();
}
}
}
string res = "";
while(!st.empty()) {
pair<char,int> tmp = st.top(); st.pop();
for(int i = 0 ; i < tmp.second ; i ++){
res += tmp.first;
}
}
return res;
}
signed main(){
cin>>n>>k;
cin>>s1>>s2;
if(k == 1){
cout<<"Yes"<<endl;
return 0;
}
ss1 = get_tag(s1);
ss2 = get_tag(s2);
//cout<<ss1<<" "<<ss2<<endl;
if(ss1 == ss2) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}