牛客网-网易2017秋招编程题集合-解题思路及源码

本文解析了八道编程题,包括回文序列、优雅的点、跳石板等,涉及双端队列模拟、动态规划等算法技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. [编程题] 回文序列

思路:本题采用双端队列来模拟题中的操作,并记录移动的次数。

源码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	deque<int> dq;
	int n,tmp,ans=0;
	cin>>n;
	while(n--)
	{
		cin>>tmp;
		dq.push_back(tmp);
	}
	while(dq.size()>1)
	{
		int f1 = dq.front();
		dq.pop_front();
		int b1 = dq.back();
		dq.pop_back();
		if(f1>b1)
		{
			int b2 = dq.back();
			dq.pop_back();
			dq.push_back(b1+b2);
			dq.push_front(f1);
			ans++;
		}
		if(b1>f1)
		{
			int f2 =dq.front();
			dq.pop_front();
			dq.push_front(f1+f2);
			dq.push_back(b1);
			ans++;
		} 
		
		
	}
	cout<<ans<<endl;
	return 0;
} 
2.[编程题] 优雅的点
思路:枚举第一区间的点,如果点在圆上,根据圆的关于原点的对称性,在第二、三、四象限也有相应的点。又因为给出的是半径的平方,那么在X轴和Y轴上也有4个点。加起来就可以得到点的数量
源码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int r,ans=0;
	cin>>r;
	for(int i=1;i<sqrt(r);i++)
	{
		double j;
		j=sqrt(r-i*i);
		if(int(j)==j)
			ans++;
	}
	if(int(sqrt(r))==sqrt(r))
	cout<<4*ans+4<<endl;
	else
	cout<<4*ans<<endl;
	return 0;
}
3.[编程题] 跳石板

思路:本题使用动态规划,采取刷表法。因为每次跳的步数为K的约数,枚举约数时,采用一次判断出,两个约数,比如j为K的约数,那么K/j也为K的约数,这样枚举的范围就从2到sqrt(K)。之后,d[i]表示到达i时,需要的最小步数。刷新d[i+j]和d[i+i/j].在进行枚举约数的之前,一定要判断现在的状态是否可达,如果不可达,跳出循环。

源码:

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn = 100000+10; 
int d[maxn],M,N;
int main()
{
	memset(d,INF,sizeof(d));
	cin>>M>>N;
	d[M]=0;
	for(int i=M;i<=N;i++)
	{ 
		if(d[i]==INF) continue;//关键剪枝 
		for (int j=2;j<=sqrt(i);j++)
		{
			if (i%j==0&&i+j<=N)//例如是2为i的约数.
				d[i+j]=min(d[i]+1,d[i+j]);
			if(i%j==0&&i+i/j<=N)//那么i/2也为i的约数
				d[i+(i/j)]=min(d[i]+1,d[i+i/j]);
		}
	} 
	if(d[N]==INF)
		cout<<-1;
	else
	{
		cout<<d[N]<<endl;
	}
	return 0;
} 
4.[编程题]暗黑字符串

思路:本题思路,查看牛客网拖仔的解析。点击打开链接

源码:

#include<iostream>
using namespace std;
//主要是推导公式:
//例如:在字符串BAA的后面只能有两种添加字符的方法
//1.添加和末尾相同的字符变成BAAA,一定不是暗黑的字符串
//2.添加和末尾不同的字符串变成BAAB或BAAC,一定不是暗黑字符串
//用dp[0]和dp[1]分别表示上一次的添加方式对应的暗黑字符串的个数
//所以公式为:dp[0] = temp0 + temp1; dp[1] = 2*temp0 + temp1;
long long blackNum(int n){
    if(n == 1)return 3;
    if(n == 2)return 9;
    long long dp[2];
    dp[0] = 3;
    dp[1] = 6;
    for(int i = 2;i<n;i++){
        long long temp0 = dp[0];
        long long temp1 = dp[1];
        dp[0] = temp0 + temp1;
        dp[1] = 2*temp0 + temp1;
    }
    return dp[0]+dp[1];
}
int main(){
    int n;
    while(cin>>n){
        cout<<blackNum(n)<<endl;
    }
    return 0;
}
5.[编程题] 数字翻转
思路:本题直接模拟操作进行,rev的操作适合在字符串的环境下,所以,我还写了string2int 和int2string函数,实际上C++自带的有int转换为string和string转int的函数。

源码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100 ;
string rev(string& s)
{
	for(int i=0;i<s.length()/2;i++)
	{
		char c;
		c=s[i];
		s[i]=s[s.length()-1-i];
		s[s.length()-1-i]=c;
	}
	return s;
}
string int2string(int a)//倒序输出 
{
	char s[maxn];
	int i=0;
	while(a)
	{
		s[i++]='0'+a%10;
		a=a/10;
	}
	s[i]='\0';
	return s;
}
int string2int(string s)
{
	int a=0;
	for(int i=0;i<s.length();i++)
	{
		a+=(s[s.length()-1-i]-'0')*pow(10,i);
	}
	return a;
}
int main()
{
	string x,y;
	cin>>x>>y;
	cout<<string2int(int2string(string2int(rev(x))+string2int(rev(y))))<<endl;
	return 0;
} 
6.[编程题] 最大的奇约数
思路:本题采用常规方法都要超时,下面的代码思路为,因为求的结果是最大奇约数的和,那么只要是奇数,奇数*2为偶数,如果这个偶数在范围内,那么结果就加这个奇数。表示奇数*2的偶数的最大奇约数为这个奇数,遍历所有奇数,并根据以上规则将所有偶数的最大奇约相加,就可得。
注意:本代码有些轻微超时,在提交牛客网系统的时,可能出现只通过80%的情况,多提交几次就AC了。算一个投机的行为吧。 

源码:

#include<stdio.h>
int main()
{
	long long  N;
	long long sum=0;
	scanf("%lld",&N);
	for(long long i=1;i<=N;i+=2)
	{
	
		int j=i;
		while(j<=N)
		{
			sum+=i;
			j=j*2;
		}				
	}
	printf("%lld\n",sum);
	return 0;
}
7.[编程题] 买苹果
思路:简单动态规划,记忆化搜索就好。

源码:

#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int solve(int n)
{
	if(n<=0) return inf;
	if(n==6) return 1;
	if(n==8) return 1;
	else
	{
		return min(solve(n-6)+1,solve(n-8)+1);
	}
}
int main()
{
	int n;
	cin>>n;
	if(solve(n)>=inf)
	cout<<-1;
	else
	cout<<solve(n)<<endl;
	return 0;
}
8.[编程题] 计算糖果

思路:本题目已知,A B C 的取值范围为-30到30的整数,那么枚举A,通过A-B算出B,通过B-C算出C。如果计算的出的A B C 满足A+B和B+C,那么就输出A B C,如果在枚举完之后,没有符合条件的A B C,则输出No就可。

源码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int A,B,C;
	int flag=0;
	int c1,c2,c3,c4;
	cin>>c1>>c2>>c3>>c4;
	for(int A=-30;A<=30;A++)
	{
		B=A-c1;
		C=B-c2;
		if(A+B==c3&&B+C==c4)
		{
			cout<<A<<" "<<B<<" "<<C<<endl;
			flag=1;
			break;
		}
	}
	if(!flag)
		cout<<"No"<<endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值