题目链接:https://codeforc.es/contest/1696/problem/C
大意:
给定一个长度为 的数组 、一个长度为 的数组 和一个数字 ,现在对数组 进行以下操作:
- 选择数组 中一个 的倍数 替换成 个
- 选择数组 中 个相同的数字 替换成
请问能否把数组 变成数组 。
数据范围:,,,。
思路:这个题最开始理解错了,所以没看出什么技巧来。在网上看了题解的大意,我看出了1操作可以通过2操作来进行逆操作,所以我们只需要把数组a和数组b全部用操作1来 拆分成子结构,然后合并成最简的子结构,即数组存储元素为num和连续个num的数量。然后再去对比数组a的结构和数组b的结构。
解决方法:有了这个思路就很好去解决了,可以用vector存储数组a和数组b拆分的子结构,一边拆分一边进行合并。合并过程可以使用vector里的erase方法。
code:
#include<bits/stdc++.h> using namespace std; #define ll long long struct number{ ll num; ll cnt; }; vector<number> va; vector<number> vb; int main() { ll t; scanf("%lld",&t); while(t--) { ll n,m,x,k; va.clear(); vb.clear(); scanf("%lld%lld",&n,&m); for(ll i=1;i<=n;i++) { scanf("%lld",&x); if(i==1||va[va.size()-1].num!=x) { va.push_back({x,1}); }else { va[va.size()-1].cnt++; } } scanf("%lld",&k); for(ll i=1;i<=k;i++) { scanf("%lld",&x); if(i==1||vb[vb.size()-1].num!=x) { vb.push_back({x,1}); }else { vb[vb.size()-1].cnt++; } } for(ll i =0;i<va.size();i++) { while(va[i].num % m == 0) { va[i].num = va[i].num/m; va[i].cnt = va[i].cnt*m; } if(i!=0 && va[i].num == va[i-1].num) { va[i-1].cnt += va[i].cnt; va.erase(va.begin()+i); i--; } } for(ll i =0;i<vb.size();i++) { while(vb[i].num % m == 0) { vb[i].num = vb[i].num/m; vb[i].cnt = vb[i].cnt*m; } if(i!=0 && vb[i].num == vb[i-1].num) { vb[i-1].cnt += vb[i].cnt; vb.erase(vb.begin()+i); i--; } } //对比 if(va.size()!=vb.size()) printf("NO\n"); else { ll i=0; for(;i<va.size();i++) { if(va[i].num!=vb[i].num||va[i].cnt!=vb[i].cnt) break; } if(i==va.size()) printf("YES\n"); else printf("NO\n"); } } }