Codeforces Global Round 21 C. Fishingprince Plays With Array

https://codeforces.com/contest/1696/problem/C

st1=21:57, ed1=22:10

st2=22:25, ed2=null

标签

数组操作

题意

给定长度为 n 的数组 a 和整数 m. 有以下 2 个操作:

  1. 选择 1 个 a[i], 且 a[i] 可以被 m 整除. 将这个 a[i] 替换为 m 个 a[i]/m.

  2. 选择长度为 m 的数列, 且 a[i] = a[i+1] = … =a[i+m-1], 将其替换为 1 个 m*a[i].

给定长度为 k 的数组 b, 判断能否在任意次操作后将 a 转化为 b.

思路

发现操作 1 和操作 2 是互逆的, 且 a -> b 等价于 b -> a.

把 a, b 都用操作 2 压缩到最短数列, 然后判断其是否相等即可.

把 a, b 都用操作 1 扩展到最长数列, 然后判断其是否相等即可.

由于扩展后数列过长, 会导致 MLE 或 RE, 只需要记录当前的 a[i] 拓展成 num 个 相同的 val, 将连续相同的 val 合并, 判断合并后的两个数组是否相等.

代码 (我太拉了)

image-20220627151609301

#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
using namespace std;

#define int long long
const int MAXN=5e4+7;
int n,m,k;

struct node{int val,num;};

vector<node> a(MAXN),b(MAXN);

signed main(){
	cin.tie(0)->sync_with_stdio(0);
	int T;cin>>T;
	while(T--){
		a.clear();
		b.clear();
		cin>>n>>m;
		int val,lena=0,lenb=0;
		FOR(i,0,n-1){
			cin>>val;
			int num=1;
			while(val%m==0 and val){
				num*=m;
				val/=m;
			}
			if(a[lena-1].val==val) a[lena-1].num+=num;
			else a[lena++]=(node){val,num};
		}
		cin>>k;
		FOR(i,0,k-1){
			cin>>val;
			int num=1;
			while(val%m==0 and val){
				num*=m;
				val/=m;
			}
			if(b[lenb-1].val==val) b[lenb-1].num+=num;
			else b[lenb++]=(node){val,num};
		}

		int eq=1;
		if(lena!=lenb) {cout<<"No\n";continue;}
		FOR(i,0,lena-1){
			if(a[i].val!=b[i].val or a[i].num!=b[i].num) {eq=0;break;}
		}
		if(eq==1) cout<<"Yes\n";
		else cout<<"No\n";
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值