Codeforces Round 685 A-E题解

本文详细解析了Codeforces Round 685中A到E题目的解题思路。A题关注如何通过有限次操作将整数n变为1;B题探讨01字符串的非连续子序列匹配;C题讨论通过特定操作使两个字符串相等的可能性;D题是关于二维平面上硬币移动的游戏策略分析;E题则涉及位运算的查询策略,提出在限制操作次数下获取所有数值的方法。

A.Subtract or Divide
题意:给定一个n,定义两种操作。
操作1:n=n-1;
操作2:n除以一个非自身的因数
问最少几次操作使得n变成1

题解:
特判一下n=1,2,3的情况
别的情况就偶数两次,奇数三次(奇数-1变成偶数)

int main() {
    for(scanf("%d",&_);_;_--){
        scanf("%d",&n);
        if (n==1){puts("0");continue;}
        if (n==2){puts("1");continue;}
        if (n==3){puts("2");continue;}
        if (n%2==0)puts("2");
        else puts("3");
    }
    return 0;
}

B.Non-Substring Subsequence
题意:给定一个01字符串,每次给定l r,问是否有非连续的子序列使得子序列与s[l]s[l+1]…s[r]子串相等.
题解:
显然可以用子串中的n-1个元素,剩下一个用别的地方就能满足了。
这样操作是最优的,因为只需在r的后面还有一个位置x,s[x]==s[r]或者在l在前面有一个y,s[y]==s[l]即可。
所以我们只需要扫一遍记录一下第一个0,1出现的位置,最后一个0,1出现位置即可

int _,n,q,l,r;
char s[maxn];
int b[2],e[2];
int main() {
    for(scanf("%d",&_);_;_--){
        scanf("%d%d",&n,&q);
        scanf("%s",s+1);
        b[0]=b[1]=e[0]=e[1]=0;
        for (int i=1;i<=n;i++)if (s[i]=='0'){b[0]=i;break;}
        for (int i=1;i<=n;i++)if (s[i]=='1'){b[1]=i;break;}
        for (int i=n;i>=1;i--)if (s[i]=='0'){e[0]=i;break;}
        for (int i=n;i>=1;i--)if (s[i]=='1'){e[1]=i;break;}
        while (q--){
        	scanf("%d%d",&l,&r);
        	if (l==b[s[l]-'0']&&r==e[s[r]-'0'])puts("NO");
        	else puts("YES");
        }
    }
    return 0;
}

C.String Equality
题意:给定两个小写字母组成的串串s,t和两种操作。
操作1:交换s[i]和s[i+1]
操作2:若s[i]…s[I+k-1]都相等且不等于a,可以让这些全部都变成字母表里下一个字母
问在无限次操作后能不能使得s变成t
题解:
那显然我们可以只看每个字母的个数了(因为顺序可以通过操作1交换得到)
然后我们把s和t共有的部分抵消,剩下的就是我们要通过操作2变换得到。
首先显然抵消后每个字母数量一定都是k的倍数
然后呢我们分别看两个串的数量前缀和判断一下就能知道能不能转换成功了

bool solve(){
	scanf("%d%d",&n,&k);
    scanf("%s",s+1);
    scanf("%s",t+1);
    for (int i=0;i<26;i++)num1[i]=num2[i]=0;
    for (int i=1;i<=n;i++)num1[s[i]-'a']++;
    for (int i=1;i<=n;i++)num2[t[i]-'a']++;
    for (int i=0;i<26;i++){
    	int cnt=min(num1[i],num2[i]);
    	num1[i]-=cnt;
    	num2[i]-=cnt;
    	if (num1[i]%k||num2[i]%k)return false;
    	num1[i]/=k;num2[i]/=k;
    }
    if (num1[0]<num2[0])return false;
    for (int i=1;i<26;i++){
    	num1[i]+=num1[i-1];
    	num2[i]+=num2[i-1];
    	if (num1[i]<num2[i])return false;
    }
    return true;
}
int main() {
    for(scanf("%d",&_);_;_--){
        printf("%s\n",solve()?"Yes":"No");
    }
    return 0;
}

D.Circle Game
题意:在一个二维平面内,有一个硬币初始在(0,0),两个人玩游戏,每个人每次只能选择让硬币的横坐标+k或者纵坐标+k,硬币到原点的欧几里得距离要小于等于d,谁不能操作就输了,问谁赢。
题解:
若当前是后手赢的状态,那么不管第一个人怎么操作,我都反着来。最后会到达一个(x,x),必须要(x+k,x)和(x,x+k)都不能走,那就是后手赢。
若是先手赢,先手先向右走,然后都跟后手反着来,最后会到达(x+k,x)且(x+k,x+k)和(x+2k,x)都不能走,就是先手赢。
所以就是简单的判断一下(x+k,x)这个点到底在不在圆内。

ll _,d,k;
bool solve(){
	scanf("%lld%lld",&d,&k);
	ll mx=0;
	for (int i=1;i<=100000;i++){
		if (1ll*i*k*i*k+1ll*i*k*i*k<=1ll*d*d)mx=i*k;
		else break;
	}
	if (mx*mx+(mx+k)*(mx+k)>d*d)return false;
	return true;
}
int main() {
    for(scanf("%lld",&_);_;_--){
        printf("%s\n",solve()?"Ashish":"Utkarsh");
    }
    return 0;
}

E.Bitwise Queries
题意:交互题,给定n(n保证为2的幂次),你可以询问a[x]和a[y]按位与,按位或,按位异或的值。E1要求n+2次完成,E2要求n+1次完成,题目保证a[i]∈\in[0,n-1]
题解:
由于我直接推出了n+1次的做法就直接讲n+1次做法了。
我们观察这个n个数无非就是两种情况。
第一种,存在a[x]=a[y]
第二种,不存在a[x]=a[y]

首先我们要有两个前置芝士
若x^y=z 则 x^z=y, y^z=x
若x^y=z ,x^k=z 则y=k
我们先用掉n-1次操作先问a[1]与a[i]的值,如果出现0说明a[i]=a[1],那么我们问一下a[1]和a[x]按位与的结果,就得到了a[1]然后就得到了全部的值
如果出现了两个相同的值也说明这两个位子的数相等,然后我们询问这两个位子的数得到了它们的值反推出a[1]然后就得到了全部的值,这种情况只用n次操作就可完成

如果没有出现上述两种情况,说明全部的数唯一的。
这个时候我们去找跟a[1]异或为1的数,设为a[x]好了,a[x]跟a[1]除了最后一位不同,别的位都一样,所以我们先询问一下a[1] AND a[x] 那就是有一个问题到底是a[1]最后一位有1还是a[x]最后一位有1呢。这个时候我们去找跟a[1]异或为3的数字,设为a[y]吧,我们询问a[x] AND a[y],若是1说明这个1在x上,若是0说明在y上(因为a[x]和a[y]在最后一位是相同的)至此我们得到了a[1]同理得到全部的数,这种情况只需n+1次操作

所以总的操作次数是n+1次

int main() {
    int flag=0;
    scanf("%d",&n);
    for (int i=2;i<=n;i++){
    	printf("XOR %d %d\n",1,i);
    	fflush(stdout);
    	scanf("%d",&v[i]);
    	if (flag==0&&p[v[i]]){
    		flag=1;
    		s1=p[v[i]];
    		s2=i;
    	}
    	else if (flag==0&&v[i]==0){
    		flag=1;
    		s1=1;s2=i;
    	}
    	p[v[i]]=i;
    }
    if (flag){
    	printf("AND %d %d\n",s1,s2);
    	fflush(stdout);
    	scanf("%d",&ans[s1]);
    	ans[s2]=ans[s1];
    	ans[1]=v[s1]^ans[s1];
    	for (int i=2;i<=n;i++){
    		if (i!=s1&&i!=s2)ans[i]=v[i]^ans[1];
    	}
    	printf("!");
    	for (int i=1;i<=n;i++)printf(" %d",ans[i]);puts("");
    }
    else{
    	printf("AND %d %d\n",1,p[1]);
    	fflush(stdout);
    	scanf("%d",&ans[1]);
    	printf("AND %d %d\n",p[1],p[3]);
    	fflush(stdout);
    	int cnt;
    	scanf("%d",&cnt);
    	if ((cnt&1)==0)ans[1]+=1;
    	for (int i=2;i<=n;i++){
    		ans[i]=v[i]^ans[1];
    	}
    	printf("!");
    	for (int i=1;i<=n;i++)printf(" %d",ans[i]);puts("");
    }
    return 0;
}
基于径向基函数神经网络RBFNN的自适应滑模控制学习(Matlab代码实现)内容概要:本文介绍了基于径向基函数神经网络(RBFNN)的自适应滑模控制方法,并提供了相应的Matlab代码实现。该方法结合了RBF神经网络的非线性逼近能力和滑模控制的强鲁棒性,用于解决复杂系统的控制问题,尤其适用于存在不确定性和外部干扰的动态系统。文中详细阐述了控制算法的设计思路、RBFNN的结构与权重更新机制、滑模面的构建以及自适应律的推导过程,并通过Matlab仿真验证了所提方法的有效性和稳定性。此外,文档还列举了大量相关的科研方向和技术应用,涵盖智能优化算法、机器学习、电力系统、路径规划等多个领域,展示了该技术的广泛应用前景。; 适合人群:具备一定自动控制理论基础和Matlab编程能力的研究生、科研人员及工程技术人员,特别是从事智能控制、非线性系统控制及相关领域的研究人员; 使用场景及目标:①学习和掌握RBF神经网络与滑模控制相结合的自适应控制策略设计方法;②应用于电机控制、机器人轨迹跟踪、电力电子系统等存在模型不确定性或外界扰动的实际控制系统中,提升控制精度与鲁棒性; 阅读建议:建议读者结合提供的Matlab代码进行仿真实践,深入理解算法实现细节,同时可参考文中提及的相关技术方向拓展研究思路,注重理论分析与仿真验证相结合。
### Codeforces Round 1005 Div. 2 A-F Problem Solutions #### A. Money Change 为了处理货币转换问题,可以将所有的金额都转化为分的形式来简化计算。通过遍历输入数据并累加各个部分的金额,最后求得剩余的钱数并对100取模得到最终结果[^2]。 ```cpp #include <iostream> using namespace std; int main() { int s, xi, yi; cin >> s; int total_cents = 0; for (int i = 0; i < s; ++i) { cin >> xi >> yi; total_cents += xi * 100 + yi; } cout << (s * 100 - total_cents) % 100 << endl; } ``` #### B. Odd and Even Pairs 此题目要求找到至少一对满足条件的索引:要么是一个偶数值的位置,或者是两个奇数值位置。程序会读入测试次数`t`以及每次测试中的数组长度`n`及其元素,并尝试找出符合条件的一对索引输出;如果没有这样的组合则返回-1[^3]。 ```cpp #include <cstdio> int main() { int t, n, num; scanf("%d", &t); while (t--) { int evenIndex = 0, oddIndex1 = 0, oddIndex2 = 0; scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%d", &num); if (num % 2 == 0 && !evenIndex) evenIndex = i; else if (num % 2 != 0) { if (!oddIndex1) oddIndex1 = i; else if (!oddIndex2) oddIndex2 = i; } if ((evenIndex || (oddIndex1 && oddIndex2))) break; } if (evenIndex) printf("1\n%d\n", evenIndex); else if (oddIndex1 && oddIndex2) printf("2\n%d %d\n", oddIndex1, oddIndex2); else printf("-1\n"); } return 0; } ``` 由于仅提供了前两道题的具体描述和解决方案,在这里无法继续给出完整的C至F题解答。通常情况下,每一道竞赛编程题都有其独特的挑战性和解决方法,建议查阅官方题解或社区讨论获取更多帮助。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值