1. 程式人生 > 其它 >2018 ICPC 南京 E. Eva and Euro coins(思維+棧)

2018 ICPC 南京 E. Eva and Euro coins(思維+棧)

技術標籤:演算法練習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; }