面试题

面试题讲解

1,可鞥吧

1,你有 n个 桶放在一排 , 从左到右开始编号分别为1~n. 最初, 第 i 桶装的水是 ai 升.

你可以把水从一个桶倒到另一个桶。 在这个过程中, 你可以两个选择两个桶 x 和y (第 x个桶不应该为空) 然后从桶x 向桶 y 倒水(可能是所有的水).你可以假设桶的容量是无限的,所以你可以在每个桶里倒入任何数量的水。

如果最多可以倒水 k 次.计算桶中最大和最小水量之间的最大可能差。

举例

如果你有四个桶,每个桶里装5升水,k=1,你可以从第二个桶里倒5升水到第四个桶里,所以桶里的水量是[5,0,5,10],最大和最小的差值是10;
如果所有的桶都是空的,你就不能做任何操作,所以最大和最小的量之差仍然是0。

Input

第一行包含一个整数 t (1 < t < 1000) — 测试用例的数量

每个测试用例的第一行包含两个整数 n 和 k(1 <= k < n < 2<= 10^5) — 桶数和可以浇注的数量。

第二行包含 n 整数 a1, a2, … an (0 <=ai <=10^9), 其中ai 是第 i 个桶的初始水量。

保证 n 个以上测试用例的总和不超过 2 * 10^5.

Output

F对于每个测试用例,如果最多可以倒水k 次,请打印桶中最大和最小水量之间的最大可能差值。

题解:

首先把所有的桶按大小排序;用一个sort函数就行了,然后倒水k次,每次从大到小给最大的桶倒水,倒k次,然后用最大的数减去最小的就行;

代码:

#include<stdio.h>
#include<algorithm>
int main()
{
	int t,n,k,i,j,p;
	scanf("%d",&t);
	for(i=0;i<t;i++)
	{
		scanf("%d%d",&n,&k);
		int a[n]={0};
		for(j=0;j<n;j++)
		{
			scanf("%d",&a[j]);
		}
		std::sort(a,a+n);
		for(p=n-2;k>0;p--)
		{
			a[n-1]=a[n-1]+a[p];
			k--;
		}
		printf("%d\n",a[n-1]-a[0]);
		
	}
	return 0;
}

2,熊熊的尝试

熊熊学长一天在实验室里闲的没事。他想做点游戏打发一下时间。他就拉上了和他同样无聊的柴柴学长。

两位学长要玩的游戏是什么呢?很简单,它是这样定义的:
1、 本游戏是一个二人游戏;
2、 有一堆石子一共有n个;
3、 两人轮流进行;
4、 每走一步可以取走1…m个石子;
5、 最先取光石子的一方为胜;

如果游戏的双方使用的都是最优策略,请输出哪个人能赢。

Input

输入数据首先包含一个正整数C(C<=100),表示有C组测试数据。
每组测试数据占一行,包含两个整数n和m(1<=n,m<=1000),n和m的含义见题目描述。

Output

如果先走的人能赢,请输出“first”,否则请输出“second”,每个实例的输出占一行。

题解:

一个简单的博弈–巴士博弈;

一共有n个物品,一次拿m个,当n=m+1时,由于一次最多只能取m个,所以无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜,所以当一方面对的局势是n%(m+1)=0时,其面临的是必败的局势。所以当n=(m+1)*r+s,(r为任意自然数,s≤m)时,如果先取者要拿走s个物品,如果后取者拿走x(≤m)个,那么先取者再拿走m+1-k个,结果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜。总之,要保持给对手留下(m+1)的倍数,就能最后获胜。

代码:

#include<stdio.h>
int main()
{
	int t,i;
	int m,n;
	scanf("%d",&t);
	for(i=0;i<t;i++)
	{
		scanf("%d%d",&n,&m);
		if(n%(m+1)==0)
		{
			printf("second\n");
		}
		else
			printf("first\n");
	}
	return 0;
}

3,咦!这是嘛呀!

现在我们有两个正整数A和B,请找出一个正整数C,使得式子( (A xor C)&(B xor C) )最小 (xor是异或运算)
当然,如果使得式子最小的C为0时,请你输出1
Input
第一行输入T,代表有T组数据
接下来每一行输入两个数A,B(A,B<=2^32)
Output
对于每一组数据输出一个正整数C

题解:

先对题目所求值打表:

ABA^BA^CB^C(A^ C)&(B^C)
000CCC
010CC0
100!CC0
111!C!C!C

4,SKY数

熊熊学长从小喜欢奇特的东西,而且天生对数字特别敏感,一次偶然的机会,他发现了一个有趣的四位数2992,这个数,它的十进制数表示,其四位数字之和为2+9+9+2=22,它的十六进制数BB0,其四位数字之和也为22,同时它的十二进制数表示1894,其四位数字之和也为22,啊哈,真是巧啊。熊熊学长非常喜欢这种四位数,由于他的发现,所以这里我们命名其为Sky数。但是要判断这样的数还是有点麻烦啊,那么现在请你帮忙来判断任何一个十进制的四位数,是不是Sky数吧。

Input

输入含有一些四位正整数,如果为0,则输入结束。

Output

若n为Sky数,则输出“#n is a Sky Number.”,否则输出“#n is not a Sky Number.”。每个结果占一行。注意:#n表示所读入的n值。

题解:

主要是进制转化,10进制转化为12进制和16进制;和其转化为2进制一样,除2取余;

代码:

#include<stdio.h>
#include<math.h>
int main()
{
	int n,i,j,k;
	int a,b;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		int sum=0;
		int num=0;
		scanf("%d%d",&a,&b);
		for(j=1;j<a;j++)
		{
			if(a%j==0)
			{
				sum=sum+j;
			}
		}
		for(k=1;k<b;k++)
		{
			if(b%k==0)
			{
				num=num+k;
			}
		}
		if(sum==b&&num==a)
		{
			printf("YES\n");
		}
		else 
			printf("NO\n");
	}
	return 0;
}

5,倩姐的自我突破

倩倩学姐,一个大三的老阿姨呢,但是呢她还有一颗坚持竞赛的心。所以他碰到一个奥林匹克竞赛的数学问题,她搞不定很难受,决定暴饮暴食。聪明而优秀的学霸熊熊学长看到这一幕决定帮他解决这个问题。这个问题是:

我们描述 K:

k! = 1 * 2 * …* (k - 1) *k

我们表示 S:

S = 1 * 1! + 2 * 2! + … +
(n - 1) * (n-1)!

然后 S 对 n 去模是 ___________

你将得到一个整数n.

你需要计算 S 对 n 取模的值

输入
第一行输入一个整数 T(T < 1000), 表示测试用例的行数.

对于每个测试用例,都有一行包含一个整数 n.

保证 2

输出
对于每个测试用例,打印一个整数 S 对 n 取模后的值.

提示
第一个测试用例 S = 1* 1!= 1, 并且 1 的模 2 运算 1.

第二个测试用例 S = 11!+2 2!= 5 , 并且 5 对 3 取模是 2.

题解:

找样例,找出多组样例,规律就是输出n-1;

代码:

#include<stdio.h>
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&a);
		printf("%d\n",a-1);
	}
	return 0;
}

6,看看就好,劝劝自己

古希腊数学家毕达哥拉斯在自然数研究中发现,220的所有真约数(即不是自身的约数)之和为:

1+2+4+5+10+11+20+22+44+55+110=284。

而284的所有真约数为1、2、4、71、 142,加起来恰好为220。人们对这样的数感到很惊奇,并称之为亲和数。一般地讲,如果两个数中任何一个数都是另一个数的真约数之和,则这两个数就是亲和数。

你的任务就编写一个程序,判断给定的两个数是否是亲和数

Input

输入数据第一行包含一个数M,接下有M行,每行一个实例,包含两个整数A,B; 其中 0 <= A,B <= 600000 ;

Output

对于每个测试实例,如果A和B是亲和数的话输出YES,否则输出NO

题解:
暴力求出两个数所有因数之和,再比较;

代码:

#include<stdio.h>
#include<math.h>
int main()
{
	int n,i,j,k;
	int a,b;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		int sum=0;
		int num=0;
		scanf("%d%d",&a,&b);
		for(j=1;j<a;j++)
		{
			if(a%j==0)
			{
				sum=sum+j;
			}
		}
		for(k=1;k<b;k++)
		{
			if(b%k==0)
			{
				num=num+k;
			}
		}
		if(sum==b&&num==a)
		{
			printf("YES\n");
		}
		else 
			printf("NO\n");
	}
	return 0;
}

7,Tyloo的S1mple本人

熊熊是一名csgo玩家,在沙二驰骋多年的他,显然已经对这个地方了如指掌。他恐怖的定位和风骚的身法以及高超的战术让他的队友后悔来到这个地方。尤其是他的大狙,当他扛着笨重的awp走到中门时,每一声枪响都会有人应声倒地。但是熊熊有个奇怪的癖好,他每一次只杀奇数个数的人,一杀他嫌太少,九杀又太多,所以他每一局他只会打出三杀,五杀或七杀。现在你在他旁边看他打游戏,你看到他杀了n个人,你现在想知道他分别打出了多少个三杀,五杀或七杀。
Input
第一行的整数 t(1<=t<=1000)— 测试用例的个数.

每个测试用例只有一个输入数据 — lrh杀人的总数 n(1<=n<=1000)

Output
如果对于某个测试样例,没有正确的答案,则输出 -1.

否则,输出3个正整数-三杀的个数,五杀的个数,七杀的个数 — 如果存在多个情况,输出任意一种即可

这提没有难度,直接看代码吧

代码:

#include<stdio.h>
int main()
{
	int t;
	int n;
	scanf("%d",&t);
	while(t--)
	{
		int s=0;
		int w=0;
		int q=0;
		int flog=1;
		scanf("%d",&n);
		if(n<5&&n!=3)
		{
			printf("-1\n");
			flog=0;
		}
		s=n/3;
		if(n%3==2)
		{
			w=1;
			s=s-1;
		}
		if(n%3==1)
		{
			s=s-2;
			q=1;
		}
		if(flog==1)
			printf("%d %d %d\n",s,w,q);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值