牛客算法周周练9 解题报告(ABD)

A 符合条件的整数(思维)

题目描述
众所周知,某个被共青团点名的学校的机房里有一个蒟蒻,名字叫做clccle,因为文化课成绩不好而经常被班主任gank,这次他遇到了一个很困(rui)难(zhi)的数学题,因为clccle非常辣鸡,所以他想到了聪明的你,你能帮Ta解决这个问题吗?
给定两个整数N,M,表示区间 [2N,2M),请求出在这个区间里有多少个整数i满足i % 7=1
输入描述:
一行,两个整数N,M 0<=N<M<=65
输出描述:
一个数字ans,表示满足条件的数字的个数
示例1
输入
2 3
输出
0
说明
在区间[2^2 , 2 ^3 )里满足条件的整数的个数为零 ,(4,5,6,7,8因为在开区间边界上所以不做考虑)

题目大意:
求2的n次方到2的m次方中 i % 7 == 1 数字的数量(左闭右开)。

解题思路:
先将2进行n次方和m次方,之后再 (m-2)/7-(n-2)/7 即可。
解释一下:为什么m和n要-2? m n 各减一是因为左闭右开,维护正确的区间,然后得到m-1和n-1,这样-1是不行的,因为要%7==1,所以要再减一,判断一下边界的数要不要就可以了。AC代码:
PS:至于为什么2^65次方为什么不爆long long 我还比较疑惑:(

#include <iostream>
typedef long long ll;
using namespace std;
ll n,m;
int main()
{
    cin>>n>>m;
    n=1LL<<n,m=1LL<<m;
    cout<<(m-2)/7-(n-2)/7<<endl;
    return 0;
}

B Relic Discovery(签到题)

题目描述
Recently, paleoanthropologists have found historical remains on an island in the Atlantic Ocean. The most inspiring thing is that they excavated in a magnificent cave and found that it was a huge tomb. Inside the construction, researchers identified a large number of skeletons, and funeral objects including stone axe, livestock bones and murals. Now, all items have been sorted, and they can be divided into N types. After they were checked attentively, you are told that there are Ai items of the i-th type. Further more, each item of the i-th type requires Bi million dollars for transportation, analysis, and preservation averagely. As your job, you need to calculate the total expenditure.
输入描述:
The first line of input contains an integer T which is the number of test cases. For each test case, the first line contains an integer N which is the number of types. In the next N lines, the i-th line contains two numbers Ai and Bi as described above. All numbers are positive integers and less than 101.
输出描述:
For each case, output one integer, the total expenditure in million dollars.
示例1
输入
1
2
1 2
3 4
输出
14

没啥好说的…签到题 每次ans+=a*b就可以了。AC代码:

#include <iostream>
using namespace std;
typedef long long ll;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int s;
		ll ans=0;
		cin>>s;
		while(s--)
		{
			ll a,b;
			cin>>a>>b;
			ans+=a*b;
		}
		cout<<ans<<endl;
	}
	//system("pause");
	return 0;
}

D 石子游戏(博弈)

题目描述
Alice和Bob在玩游戏,他们面前有n堆石子,对于这些石子他们可以轮流进行一些操作,不能进行下去的人则输掉这局游戏。
可以进行两种操作:

  1. 把石子数为奇数的一堆石子分为两堆正整数个石子
  2. 把两堆石子数为偶数的石子合并为一堆

两人都足够聪明,会按照最优策略操作。现在Alice想知道自己先手,谁能最后赢得比赛。
输入描述:
第一行一个正整数n。(1<=n<=104)
接下来第二行n个正整数表示每堆石子的数量。每堆石子不超过105个。
输出描述:
Alice或者Bob,表示谁能最后赢得游戏。
示例1
输入
3
3 2 2
输出
Alice
说明
Alice只要现将两个石子数量为2的堆合并为一堆4个石子,Bob就只能把3分为两堆1和2,接下来Alice只要将2和4合并,Bob输掉了这局游戏。

题目大意:
由Alice先手,每个人都可以进行题目中所描述的操作,谁最后无法操作谁就输了。

解题思路:
1的情况显然不用考虑,因为1对哪一种操作来说都是不合法的,特判一下全是1的情况,如果全是1显然Alice输了,设大于1的奇数个数为a,大于1的偶数个数为b,我们可以计算一下,如果有b个偶数,那么显然偶数要全合并要操作(b-1)次,而一个奇数可以分解成1和一个偶数,一共有a个奇数,所以偶数的操作次数就是(a+b-1)次,奇数操作就是a次,**注意一下:**奇数的最优解一定是分解成(x,x-1),可以自己造一组数据,奇数最后一定会被分解成1和n个偶数,而这n个偶数合并后得到的就是x-1,而合并操作一定是2的倍数次,%2以后为0,所以不考虑,所以最优解一定是(x,x-1),那么奇数可以操作的就是a次,一共要操作的a+a+b-1次,我用cnt记录所有大于1的数字(a+b),用cnt1记录大于1的偶数(b),最后判断一下(cnt+cnt1-1)的奇偶性就可以了。AC代码:

#include <iostream>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int cnt=0,cnt1=0,one=0;
	for(int i=1;i<=n;i++)
	{
		int s;
		cin>>s;
		if(s==1)//特判全1
		{
			one++;
			continue;
		}
		if(s%2)
		{
			cnt++;
			cnt1++;
		}
		else
		  cnt1++;
	}
	if((cnt+cnt1-1)%2&&one!=n)//奇数次一定是Alice胜
	  cout<<"Alice"<<endl;
	else
	  cout<<"Bob"<<endl;
	//system("pause");
	return 0;
}
posted @ 2020-06-03 16:53  Hayasaka  阅读(70)  评论(0编辑  收藏  举报