牛客练习赛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;
}