2017年3月18日奇虎360 笔试真题

360笔试的编程题有3个,前面2个我都提交并AC了,最后一个刚刚写完准备提交然而笔试刚刚结束,实在有些可惜。后来在赛码网提交了,发现也是AC的。

本文中题目来源:赛码网,代码来源:笔试中写的原代码。

(3个题目的顺序是我笔试时候的顺序,和赛码网的不一样)

1,跑步(数学计算)

跑步(奇虎360 2017春招真题)

小明同学喜欢体育锻炼,他常常去操场上跑步。跑道是一个圆形,在本题中,我们认为跑道是一个半径为R的圆形,设圆心的坐标为原点(0,0)。

小明跑步的起点坐标为(R,0),他沿着圆形跑道跑步,而且一直沿着一个方向跑步。回到家后,他查看了自己的计步器,计步器显示他跑步的总路程为L。

小明想知道自己结束跑步时的坐标,但是他忘记自己是沿着顺时针方向还是逆时针方向跑的了。他想知道在这两种情况下的答案分别是多少。

输入

输入两个整数L,R (1<=L,R<=100)。

样例输入

1 2

输出

输出两行,每行两个数,用空格隔开。第一行的两个数为顺时针情况下结束位置的坐标,第二行是逆时针情况下结束位置的坐标。所有数据小数点后四舍五入保留3位。

样例输出

1.755 -0.959

1.755 0.959

我的代码:

#include <iostream>
#include<math.h>
using namespace std;

int main()
{
	double l, r, x, y;
	cin >> l >> r;
	x = r*cos(l / r), y = r*sin(l / r);
	printf("%.3f %.3f\n%.3f %.3f", x,-y,x,y);
	return 0;
} <iostream>
#include<math.h>
using namespace std;

int main()
{
	double l, r, x, y;
	cin >> l >> r;
	x = r*cos(l / r), y = r*sin(l / r);
	printf("%.3f %.3f\n%.3f %.3f", x,-y,x,y);
	return 0;
}

2,剪气球串(动态规划)

剪气球串(奇虎360 2017春招真题)

小明买了一些彩色的气球用绳子串在一条线上,想要装饰房间,每个气球都染上了一种颜色,每个气球的形状都是各不相同的。我们用1到9一共9个数字表示不同的颜色,如12345则表示一串5个颜色各不相同的气球串。但小明希望得到不出现重复颜色的气球串,那么现在小明需要将这个气球串剪成多个较短的气球串,小明一共有多少种剪法?如原气球串12345的一种是剪法是剪成12和345两个气球串。

注意每种剪法需满足最后的子串中气球颜色各不相同(如果满足该条件,允许不剪,即保留原串)。两种剪法不同当且仅当存在一个位置,在一种剪法里剪开了,而在另一种中没剪开。详见样例分析。

输入

第一行输入一个正整数n(1≤n≤100000),表示气球的数量。

第二行输入n个整数a1,a2,a3...an,ai表示该气球串上第i个气球的颜色。对于任意i,有1≤ai≤9。

样例输入

3

1 2 3

输出

输出一行,第一行输出一个整数,表示满足要求的剪法,输出最终结果除以1000000007后的余数。

样例输出

4

我的代码:

#include <iostream>
using namespace std;

int l[100000], ans[100000][10];

int main()
{
	const int p = 1000000007;
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)cin >> l[i];
	for (int i = 1; i <= 9; i++)ans[0][i] = 1;
	for (int i = 1; i < n; i++)
	{
		for (int j = 1; j <= 9; j++)
		{
			if (j == l[i - 1])
			{
				ans[i][j] = ans[i - 1][l[i - 1]];
				continue;
			}
			ans[i][j] = ans[i - 1][l[i-1]] * 2 % p;
			for (int k = i - 1; k >= i-10; k--)
			{
				if (l[k] == l[i - 1] && k < i - 1)break;
				if (l[k] == j)
				{
					ans[i][j] = (ans[i-1][j]+ans[i-1][l[i-1]])%p;	
					break;
				}
			}
		}
	}
	cout << ans[n - 1][l[n - 1]];
	return 0;
} <iostream>
using namespace std;

int l[100000], ans[100000][10];

int main()
{
	const int p = 1000000007;
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)cin >> l[i];
	for (int i = 1; i <= 9; i++)ans[0][i] = 1;
	for (int i = 1; i < n; i++)
	{
		for (int j = 1; j <= 9; j++)
		{
			if (j == l[i - 1])
			{
				ans[i][j] = ans[i - 1][l[i - 1]];
				continue;
			}
			ans[i][j] = ans[i - 1][l[i-1]] * 2 % p;
			for (int k = i - 1; k >= i-10; k--)
			{
				if (l[k] == l[i - 1] && k < i - 1)break;
				if (l[k] == j)
				{
					ans[i][j] = (ans[i-1][j]+ans[i-1][l[i-1]])%p;	
					break;
				}
			}
		}
	}
	cout << ans[n - 1][l[n - 1]];
	return 0;
}

3,分金子(动态规划的备忘录方法)

分金子(奇虎360 2017春招真题)

A、B两伙马贼意外地在一片沙漠中发现了一处金矿,双方都想独占金矿,但各自的实力都不足以吞下对方,经过谈判后,双方同意用一个公平的方式来处理这片金矿。处理的规则如下:他们把整个金矿分成n段,由A、B开始轮流从最左端或最右端占据一段,直到分完为止。 

马贼A想提前知道他们能分到多少金子,因此请你帮忙计算他们最后各自拥有多少金子?(两伙马贼均会采取对己方有利的策略)

输入

测试数据包含多组输入数据。输入数据的第一行为一个正整数T(T<=20),表示测试数据的组数。然后是T组测试数据,每组测试数据的第一行包含一个整数n,下一行包含n个数(n <= 500 ),表示每段金矿的含金量,保证其数值大小不超过1000。

样例输入

6

4 7 2 9 5 2

10

140 649 340 982 105 86 56 610 340 879

输出

对于每一组测试数据,输出一行"Case #id: sc1 sc2",表示第id组数据时马贼A分到金子数量为sc1,马贼B分到金子数量为sc2。详见样例。

样例输出

Case #1: 18 11

Case #2: 3206 981

我的代码:

#include <iostream>
using namespace std;

double num[500], ans[500][500];

double f(int l, int r)
{
	if (l > r)return 0;
	if (ans[l][r])return ans[l][r];
	if (l == r)return num[r];
	double x1 = num[l] + f(l + 2, r), x2 = num[r] + f(l+1, r - 1);
	if (x1 > num[l] + f(l + 1, r - 1))x1 = num[l] + f(l + 1, r - 1);
	if (x2 > num[r] + f(l, r - 2))x2 = num[r] + f(l, r - 2);
	if (x1 > x2)ans[l][r] = x1;		
	else ans[l][r] = x2;
	return ans[l][r];
}

int main()
{
	int t, n;
	double s;
	cin >> t;
	for (int ca = 1; ca <= t;ca++)
	{
		s = 0;
		cin >> n;
		for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)ans[i][j] = 0;
		for (int i = 0; i < n; i++)
		{
			cin >> num[i];
			s += num[i];
		}
		cout << "Case #" << ca <<": " <<f(0, n - 1) <<" "<< s - f(0, n - 1)<<endl;  
	}
	return 0;
} <iostream>
using namespace std;

double num[500], ans[500][500];

double f(int l, int r)
{
	if (l > r)return 0;
	if (ans[l][r])return ans[l][r];
	if (l == r)return num[r];
	double x1 = num[l] + f(l + 2, r), x2 = num[r] + f(l+1, r - 1);
	if (x1 > num[l] + f(l + 1, r - 1))x1 = num[l] + f(l + 1, r - 1);
	if (x2 > num[r] + f(l, r - 2))x2 = num[r] + f(l, r - 2);
	if (x1 > x2)ans[l][r] = x1;		
	else ans[l][r] = x2;
	return ans[l][r];
}

int main()
{
	int t, n;
	double s;
	cin >> t;
	for (int ca = 1; ca <= t;ca++)
	{
		s = 0;
		cin >> n;
		for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)ans[i][j] = 0;
		for (int i = 0; i < n; i++)
		{
			cin >> num[i];
			s += num[i];
		}
		cout << "Case #" << ca <<": " <<f(0, n - 1) <<" "<< s - f(0, n - 1)<<endl;  
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值