今天参加了HAUT2016级新生周赛(四),第四场比赛,做了题分享一下思路,给大家分享,以及自己做个记录。
比赛网址链接如下:
http://218.28.220.249:50015/JudgeOnline/
总共出了6题,做了5个题,把做了的分享一下:
Problem A:
ykc的简单数学题
题目分析:
本题要让我们求拐点的数目,根据题目的描述,所谓拐点,就是斜率由正变成负,或者由负变成正的点。所以我们的目的就是要找到这些点。于是做一次遍历,把每一个有这种情况的点都拿出来就ok了。
代码如下:
#include<iostream>
using namespace std;
const int SIZE = 1000;
int main(){
int n;
int num[SIZE]={0};
cin>>n;
for(int i=0;i<n;++i){
cin>>num[i];
}
if(n <= 2){
cout<<0<<endl;
}else{
int flag = num[1]-num[0];
int total = 0;
for(int i=2;i<n;++i){
if((num[i]-num[i-1])*flag < 0){
total += 1;
}
flag = num[i]-num[i-1];
}
cout<<total<<endl;
}
return 0;
}
Problem C:
1的个数
题目分析:
本题要求我们求一个数的二进制表示中有多少个1。由题意,一个最直接的想法就是%2来统计1的个数,以此思想进行循环就可以了。
代码如下:
#include<iostream>
using namespace std;
int main(){
int M;
cin>>M;
int count=0;
while(M>0){
if(M%2 == 1){
count +=1;
}
M/=2;
}
cout<<count<<endl;
return 0;
}
Problem D:
约瑟夫环
题目分析:把这个问题转化为数学问题,模拟这个过程,并排序重新编号,问题变成当有2个人的时候(N=2),报道(M-1)的人出列,最后出列的应该是在只有一个人时,报数时得到的最后自出列的序号加上M,因为报到M-1的人已经出列,只剩下2个人,另一个出列者就是最后者,用函数表示:
F(2)=F(1)+M
可以得到递推公式:
F(i)=F(i-1)+M
因为可能会超出总人数范围,所以要求模
F(i)=(F(i-1)+M)%i
把公式代换进本题就可以
代码如下:
#include <iostream>
using namespace std;
int main(){
int n, m, s = 0;
cin>>n>>m;
for (int i = 2; i <= n; i++){
s = (s + m) % i;
}
cout<<s+1<<endl;
return 0;
}
Problem E:Beru-taxi
题目分析:已知你的坐标和n个司机的坐标和速度,求上车的最短时间 ,直接写就可以
代码如下:
#include<iostream>
#include<math.h>
#include<iomanip>
#include<stdio.h>
using namespace std;
const int N = 1000;
int main(){
double a,b;
double x,y,v;
int n;
double len,min=99999.00;
cin>>a>>b;
cin>>n;
for(int i=0;i<n;++i){
cin>>x>>y>>v;
len = sqrt((x-a)*(x-a)+(y-b)*(y-b))/v;
if(min>len){
min = len;
}
}
printf("%.4f\n",min);
return 0;
}
Problem F:
零钱问题
题目分析:,这是一个找零钱算法。
代码如下:
#include <iostream>
using namespace std;
int getMin(int x);
int main(){
int m, n, t;
cin>>t;
m = 100-t;
n = getMin(m);
cout<<m<<" "<<n<<endl;
return 0;
}
int getMin(int x){
int money[5] = {50,10,5,2,1};
int total = 0;
while(x>0){
for(int i=0;i<5;++i){
if(x-money[i]>=0){
total+=1;
x-=money[i];
break;
}
}
}
return total;
}