牛客练习赛69 A.时间复杂度 ,B - 划分

牛客练习赛69 A.时间复杂度

题目描述
DK 想出一道超级没有素质的题

DK 给了你一个标准的时钟,初始时间在 12:00

每分钟分针会顺时针转动 6°,而时针会顺时针转动 0.5°

DK 想知道,t 分钟后,时针和分针的较小夹角的大小是多少

由于这题超级没有素质,所以你需要将答案四舍五入到整数

输入描述:
第一行一个整数 n,表示数据组数

第 2 ~ n+1行,每行一个整数 t,意义见题目描述

输出描述:
输出n行,每行一个整数,表示答案

示例1
输入
2
180
360
1
2
3
输出
90
180
1
2
就在这里详细地分析一下,首先观察数据,小于720,也就是说时针最大也就是 360°,而分钟每 60 分钟一圈,我们可以进行缩小,即 p 1 = t ∗ 6 % 360
因为时针每圈 0.5 度,为了避免精度问题,全用整型考虑:
1分钟数为偶数,此时度数一定全为整数,正常算即可
2.分钟数为奇数,我们再考虑细一点,
第一种:如果时针角度小于分针角度,分钟数 p1 为固定的整数,考虑四舍五入,相减多出来的 0.5 一定会进位,所以答案就是 a n s = n− ( time − 1 ) / 2 (因为当变为减数如果是四舍五入的话,可以考虑把数变小,可以直接减一除二,就会变成小的数减出来就相当于进位了),
第二种:如果时针角度大于分针角度,考虑四舍五入不难发现答案就是 a n s = ( time + 1 ) / 2-n (当作为被减数的时候可以考虑把数变大,相当于提前进位,之后进行运算,是一样的),别忘了考虑另一个角。(这个实在是不理解的同学,可以带一个数试试,就会明白很多)
如果诸位遇到坑点一直做不出来,就可以像我上面那样分情况一步一步分析,答案就出来了,AC代码如下:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std; 
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int n;
int m;
int main(int argc, char** argv) {
	int t,time,sum;
	cin>>t;
	while(t--){
		cin>>time;
		int n=6*time;
		while(n>=360) n=n-360;
		if(time%2==0){
			m=time/2;
			//这里是因为还有差值可能是大于180,因为要选比较小的角
			//所以需要进行比较
			cout<<min(abs(n-m),360-abs(n-m))<<endl;;
		}else{
			double n1=double(n);
			double m1=double(time)/2;
			if(m1>n1){
				cout<<min((time+1)/2-n1,360-((time-1)/2-n1))<<endl;
			}else{
				cout<<min(n1-(time-1)/2,360-(n1-(time+1)/2))<<endl;
			}
		}
	}
	return 0;
}

B - 划分

题目就不给了O(∩_∩)O哈哈~懒得复制了
题意: 给定 n 个数,一个 x表示可以划分成最多 x 个串,一个 y 表示在一个串中最多选择 y个数。
将 n 个数划分成 i 个串,在每个串中选择 j个最大的数他们的和。
题解: 其实这道题没说我可不可以自由组合,所以其实就是一个比较简单的贪心类题型,你可以把最大的ij个数找出来,让他们分别放在j个数组中,这样的话我们只需要求出那ij个最大数的和就行了,考虑下将 n个数分成 i个串,那么总共需要选择 i × j 个数。其实就是选择前 i × j 个最大的数。当一个串中数的个数大于 j ,那么该串的 [j+1,本串最后的位置](这些相对较小的数)这些数一定都不会被选择。但是考虑下可能这些数是前 i × j 个最大的数之一,所以如果存在这种情况,这样的串就会被再次切割到其他串中。最终一定能保证每个串中取到的一定是前 i × j 个最大的数。
AC的代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std; 
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
const int  maxn=100005;
int n;
int f[maxn];
long long f1[maxn];
int main(int argc, char** argv) {
	cin>>n;
	memset(f,0,sizeof(f));
	for(int i=1;i<=n;i++){
		cin>>f[i];
	}
	sort(f+1,f+1+n);
	//颠倒一下
	reverse(f+1,f+1+n);
	memset(f1,0,sizeof(f1));
	//求前i最大的数的和
	for(int i=1;i<=n;i++){
		f1[i]=f1[i-1]+f[i];
	}
	long long ans=0;
	int x,y;
	cin>>x>>y; 
	for(int i=1;i<=x;i++){
		for(int j=1;j<=y;j++){
			ans=ans+f1[i*j];
		}
	}
	cout<<ans<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值