东华进阶oj51-60

这篇博客介绍了东华oj中一道关于寻找幸运数的题目,作者分享了解题思路并提供了Java代码实现。由于网上资源多为Java版本,作者希望未来能将代码转化为C++,并邀请读者如有C++解决方案可在评论区分享。
摘要由CSDN通过智能技术生成

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
string s1,s2;
int n;
int ans=INF;
int d[6]={
   -3,-2,-1,1,2,3};
int step;
map<string,int> mp;
struct P{
   
	string x;
	int k;
};
int bfs(int u,string s){
   
	queue<P> q;
	P t={
   s,u};
	q.push(t);
	mp[s]=1;
	while(q.size()){
   
		P g=q.front();
		q.pop();
		int k=g.k;
		string x=g.x;
		//cout<<x<<endl;
		for(int i=0;i<6;i++){
   
			string y=x;
			int kk=k+d[i];
			if(kk<0||kk>=n) continue;
			swap(y[k],y[kk]);
			if(mp[y]) continue;
			P b={
   y,kk};
			mp[y]=mp[x]+1;
			if(y==s2){
   
				return mp[y];
			}
			q.push(b);
			//cout<<x<<endl;
		}
	}
	return 1;
}
int main(){
   
	cin>>s1>>s2;
	n=s1.length();
	int start;
	for(int i=0;i<n;i++){
   
		if(s1[i]=='*'){
   
			start=i;
		}
	}
	//cout<<n<<" "<<start<<endl;
	ans=bfs(start,s1);
	cout<<ans-1<<endl;
	return 0;
}

在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;

int main()
{
   
	int n,k,x;
	long long  a[100005]={
   0},sum=0;  //long long的最大值:9223372036854775807(>10^18)

	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++)
	{
   
		scanf("%d",&x);
		sum+=x;        //a[i]的前缀和
		a[sum%k]++;		//将前缀和模k的值相同的区间放在一起
	}
    long long ans=0;
	for(int i=0;i<k;i++)
	{
   
		ans+=a[i]*(a[i]-1)/2;  //前缀和模k相同的区间中任意挑两个区间可产生一个k倍区间
	}
	ans+=a[0];  //最终结果加上前缀和模k为0的区间(区间自身就是k倍区间,无需组合)
	cout<<ans<<endl;
	return 0;
}


在这里插入图片描述
在这里插入图片描述

#include<iostream>
#define N 102
using namespace std; 
int main(){
   
  int a[N],b[N];
    int n = 0,i,j,k,sum = 0;
      while(cin>>a[n])n++;//存储又有多少个小和尚 
     for(i=1; i<n; i++)b[i-1] = a[i] - a[i-1] - 1;// 进行Nim博弈的转换 
       for(i=0; i<n-1; i+=2) sum ^= b[i];//进行异或 
    if(sum==0)cout<<-1<<endl;//若开始局面为0 则必输 
    else//若非0 则必赢,因此 需要找到第一步 将局面变为0 的步骤 
    {
   
        for(i=0; i<n-1; ++i)//枚举移动第i堆  使得剩下的局面异或等于0,
            for(j=1; a[i]+j<a[i+1]; ++j) {
   //枚举可以移动的步数  保证 前项移动j 步后 不会超过后项 
			    b[i] -= j;//拿走 j个 ,这里代表 前一个向上移动j步 
                if(i!=0)b[i-1] += j;//它的后一堆b[i]向取走了j个,那莫前一堆 b[i-1] 则要增加j个 第一堆除外 
            sum = 0;
            for(k=0; k<n-1; k+=2) sum ^= b[k];//重新计算局面, 
		   if(sum==0) {
   cout<<a[i]<<" "<<a[i]+j<<endl; break;}//若变成0  则后手必败,先手必赢。跳出即可; 
            b[i] += j;//回溯 这不是必赢的操作 
            if(i
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
杭州电子科技大学在线评测系统(杭电OJ)中的题目1000-1100是一系列编程题,我将分别进行回答。 1000题是一个简单的入门题,要求计算两个整数的和。我们可以使用一个简单的算法,读取输入的两个整数,然后将它们相加,最后输出结果即可。 1001题是一个稍微复杂一些的题目,要求实现字符串的逆序输出。我们可以使用一个循环来逐个读取输入的字符,然后将这些字符存储在一个数组中。最后,我们可以倒序遍历数组并将字符依次输出,实现字符串的逆序输出。 1002题是一个求最大公约数的问题。我们可以使用辗转相除法来解决,即先求出两个数的余数,然后将被除数更新为除数,将除数更新为余数,直至两个数的余数为0。最后的被除数就是最大公约数。 1003题是一个比较简单的排序问题。我们可以使用冒泡排序算法来解决,即每次比较相邻的两个元素,如果它们的顺序错误就交换它们的位置。重复这个过程直至整个数组有序。 1100题是一个动态规划问题,要求计算给定序列中的最长上升子序列的长度。我们可以使用一个数组dp来保存到达每个位置的最长上升子序列的长度。每当遍历到一个位置时,我们可以将其和之前的位置比较,如果比之前位置的值大,则将其更新为之前位置的值加1,最后返回dp数组的最大值即可。 以上是对杭电OJ1000-1100题目的简要回答,涉及了一些基本的编程知识和算法思想。希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值