牛客网-网易2017春招笔试真题编程题集合-解题思路及源码

一、双核处理

本题目是0-1背包的变种,题目的目标是求最少需要处理的时间。可以将目标转化为在 总任务长度/2的时间内,一个CPU最多能处理的任务量,那么答案为 总任务量-在总任务长度/2的时间内最多工作量。 因为工作时间的理想最小值为总任务长度/2,那么如果一个cpu的处理时间大于总任务长度/2,那么另外一个CPU就必然小于总任务长度/2。目标实际上就转化为处理少的那个CPU尽量逼近理想值。

代码如下:

#include
using namespace std;
const int maxn = 55;
const int maxh=4096*26;
int d[2][maxh];
int main()
{
	int n,a[maxn],sum=0;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		a[i]/=1024;
		sum+=a[i];
	}
	
	for(int i=n;i>0;i--)
		for(int j=0;j<=sum/2;j++)
		{
			d[i&1][j]=(i==n?0:d[(i+1)&1][j]);
			if(j>=a[i])
				d[i&1][j]=max(d[i&1][j],d[(i+1)&1][j-a[i]]+a[i]);
		} 
	int ans = max (d[1][sum/2],sum-d[1][sum/2]);
	cout<
二、赶去公司


本题目直接枚举出各种情况下的值,就可以得到答案。

代码如下:

#include
using namespace std;
const int maxn=10000+100;
int computedis(int x1,int y1,int x2,int y2)
{
	return abs(x1-x2)+abs(y1-y2);
}
int main()
{
	int n,tx[maxn],ty[maxn],gx,gy,walktime,taxitime,ans;
	cin>>n;
	for(int i=0;i>tx[i];
	for(int i=0;i>ty[i];
	cin>>gx>>gy;
	cin>>walktime>>taxitime;
	ans=computedis(0,0,gx,gy)*walktime;
	for(int i=0;itmp)
			ans=tmp;
	}
	cout<

三、调整队形

本题目可以设想两种情况一种为G开通,一种为B开头。比如GGBGG,需要移动后面两个到前面,实际上一个G的移动次数等于G中间B的个数,上面例子中有2个G要移动B的个数为1,那么2*1=2.只需要两次就能调整完。

代码如下:

#include
using namespace std;
int main()
{
	//freopen("datain.txt","r",stdin);
	string s;
	cin>>s;
	char start;
	start = s[0];
	int cnt=0,ans=0,ans2=0;
	int i=1;
	while(start==s[i]) i++;
	for(;ians)
	cout<
四、消除重复元素

本题可以构建一个结构体存储数字的值和位置,通过值来判断重复,通过位置来帮助输出。

#include
using namespace std;
const int maxn=1000+10;
struct num 
{
	int value;
	int pos;
	bool operator < (const num n1) const{
		return  pos< n1.pos;
	}
};

int main()
{
	int n,len=0;
	num num1[maxn];
	cin>>n;
	for(int i=0;i>x;
		for(int j=0;j
五、魔力手环

本题目因为计算量太大,不能直接枚举。采用快速幂矩阵的方式,进行状态的快速变换。具体可以参考点击打开链接,通过将每次状态变化,转换成矩阵的乘法,通过矩阵运算来降低算法的复杂度。

代码如下:

#include
using namespace std;
//构建快速幂矩阵
const int maxn=50+10;
int ans[maxn];
int anspre[maxn];
int fast[maxn][maxn]; 
int fastpre[maxn][maxn];
int n,k;
int compute(int i,int j,int fast[maxn][maxn])
{
	int sum=0;
	for(int k=0;k>n>>k; 
	for(int i=0;i>ans[i];
	} 
	for(int i=0;i>1;
		for(int i=0;i
六、工作安排

因为工作只有6种,那么直接枚举可能就行。

代码如下:

#include
using namespace std;
const int maxn = 10;
int n,work[maxn][maxn],ans=0;
bool judge(int *A)
{
	int flag=true;
	for(int i=0;i>n;
	for(int i=0;i>s;
		for(int j=0;j
七、集合

本题也是采取暴力方式求解,使用map存储已经获得的元素,避免重复输出。

#include
using namespace std;
int main()
{
	map mp1;
	int w,x,y,z,ans=0;
	cin>>w>>x>>y>>z;
	for(int i=w;i<=x;i++)
		for(int j=y;j<=z;j++)
		{
			double tmp=(double)i/j;
			if(!mp1.count(tmp))
			{	
				ans++;
				mp1[tmp]=1;
			}
		}
	cout<
八、奇怪的表达式求值

本题目采用1个双端队列存储操作数,1个队列存储操作符,就能满足题目要求。

代码如下:

#include
using namespace std;
int main()
{
	deque dq1;
	deque dq2;
	string s;
	cin>>s;
	for(int i=0;i
九、涂棋盘

根据题目数格子就行。

#include
using namespace std;
const int maxn = 50+10;
int main()
{
	int n;
	char G[maxn][maxn];
	cin>>n;
	for(int i=0;i>s;
		for (int j=0;j

十、小易记单词

本题目使用map来存储准确答案,当输入的答案存在map中的时候,得分。否则不得分。

#include
using namespace std;
const int maxn=60;
int main()
{
	//freopen("datain.txt","r",stdin);
	map mp;
	string ans[maxn];
	int n,m,res=0;
	cin>>n>>m;
	for(int i=0;i>ans[i];
	}
	for(int i=0;i>s;
		mp[s]=1;
	}
	for(int i=0;i
十一、堆砖块

本题目使用动态规划,需要将优化目标进行转换,具体可以参考点击打开链接,采用动态规划的时候,可能出现空间不够的情况,参考链接中的方法直接使用 &1 的方式,也就是滚动数组的方式,值得学习。另外一种是采用枚举+剪枝。这个方法也理解比动态规划简单。

十二、分饼干
本题目,直接枚举只有50%的通过率。因为取余运算可以这样表示 1120%7=(1000%7+100%7+20%7+0%7)%7,那么采用d[i][j]表示在前i位后,余数为j的数量。当位数不为X的时候,数量不会增加,但是会转移,比如前2为时候余数1的数量为1,第3位不为X的话,那么余数1的那个数量1可能会转移到余数2等等。当为X的时候,数量会转移也会增加。

#include
using namespace std;
const int maxn=20;
const int maxm=100000;
long long d[maxn][maxm];
int main()
{
	//freopen("datain.txt","r",stdin);
	long long n;
	string s;
	cin>>s;
	cin>>n;	
	int tmp1=(long long)((s[0]-'0')*pow(10,s.length()-1))%n;
	d[1][tmp1]=1;
	for(int i=1;i









你可能感兴趣的:(牛客网笔试题)