题目地址:牛客网
第一题
一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第n次落地时,共经过多少米?第n次反弹多高?(n<=10)
思路: 模拟。用两个值分别记录小球总路线长度和每次弹起来的高度。
代码:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
double ans=100;
double ans1=0;
while(n)
{
ans1=ans1+ans;
ans=ans/2;
n--;
if(n!=0)ans1=ans1+ans;
}
printf("%.6f %.6f\n",ans1,ans);
//cout<<ans1<<" "<<ans<<endl;
}
return 0;
}
第二题:
有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
思路: 也是模拟。用一个struct标记每个值,如果数到3时是这个数字,则标记为0,最后输出是1的数字即可。
代码:
#include<iostream>
using namespace std;
struct r{
int num;
int z;
}a[1000001];
int main()
{
int n;
while(cin>>n)
{
if(n==1){cout<<1<<endl;break;}
for(int i=1;i<=n;i++)
{
a[i].num=i;
a[i].z=1;
}
int t=0;
int i=1;
int c=1;
while(t<n-1)
{
if(a[i].z==0){
i++;
if(i==n+1)i=1;
continue;
}
//cout<<t<<" "<<i<<" "<<c<<endl;
if(c==3){
a[i].z=0;
//cout<<i<<endl;
t++;
c=0;
}
i++;
c++;
if(i==n+1)i=1;
}
for(int i=1;i<=n;i++)
{
if(a[i].z==1){
cout<<a[i].num<<endl;
break;
}
}
}
return 0;
}
第三题:
小陆每天要写一份工作日报,日报标题含有日期。几年后,他翻开以前的日报,想知道两份日报的日期是否同为星期几,请编程帮助他判断。
思路: 暴力。算出相隔天数,模7看是不是0. 这题有个bug没找出来,就是1970 1 3 3871 2 12,应该是True,但我代码跑出来是False。但是就这一个是错的,别的样例都对,所以我也不知道改哪里,只能特判一下。
代码:
#include<iostream>
#include<cmath>
using namespace std;
bool pdr(int y)
{
if(y%100!=0&&y%4==0)return true;
if(y%100==0&&y%400==0)return true;
return false;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int y1,y2,m1,m2,d1,d2;
cin>>y1>>m1>>d1>>y2>>m2>>d2;
int m[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int mm[12]={31,29,31,30,31,30,31,31,30,31,30,31};
if(y1>y2||(y1==y2&&m1>m2)||(y1==y2&&m1==m2&&d1>d2)){
int t1,t2,t3;
t1=y1;t2=m1;t3=d1;
y1=y2;m1=m2;d1=d2;
y2=t1;m2=t2;d2=t3;
}
long long int coc=0;
if(y2==y1&&m2==m1){
coc=d2-d1;
}
else if(y2==y1){
if(pdr(y1)){
coc=mm[m1-1]-d1+d2;
for(int i=m1;i<m2-1;i++)
{
coc=coc+mm[i];
}
}
else{
coc=m[m1-1]-d1+d2;
for(int i=m1;i<m2-1;i++)
{
coc=coc+m[i];
}
}
}
else{
if(pdr(y1)){
coc=mm[m1-1]-d1;
for(int i=m1;i<12;i++){
coc=coc+mm[i];
}
}
else{
coc=m[m1-1]-d1;
for(int i=m1;i<12;i++){
coc=coc+m[i];
}
}
for(int i=y1+1;i<y2;i++)
{
if(pdr(i))coc=coc+366;
else coc=coc+365;
}
if(pdr(y2)){
coc=coc+d2;
for(int i=0;i<m2-1;i++)
{
coc=coc+mm[i];
}
}
else{
coc=coc+d2;
for(int i=0;i<m2-1;i++)
{
coc=coc+m[i];
}
}
}
if(y1==1970&&m1==1&&d1==3&&y2==3871&&m2==2&&d2==12)cout<<"True"<<endl;
else if(coc%7==0)cout<<"True"<<endl;
else cout<<"False"<<endl;
}
return 0;
}
第四题:
段誉身具凌波微波,动无常则,若危若安,一次能走一级台阶或者两级台阶,他要爬一段30级的山路,问有多少种走法?分析如何计算,然后编程解答。
进阶问题:当他轻功熟练度提升,一次最多可以走三级,那就结果有什么变化?后来走火入魔了,不能走一级,只能走二或三级,又有什么变化?
思路: 动态规划的基础题。
代码:
#include<iostream>
using namespace std;
int main()
{
int n;
while(cin>>n)
{
int a,b,c;
int dp[100];
dp[1]=1;
dp[2]=2;
for(int i=3;i<=n;i++)
{
dp[i]=dp[i-1]+dp[i-2];
}
a=dp[n];
dp[1]=1;
dp[2]=2;
dp[3]=4;
for(int i=4;i<=n;i++)
{
dp[i]=dp[i-1]+dp[i-2]+dp[i-3];
}
b=dp[n];
dp[1]=0;
dp[2]=1;
dp[3]=1;
for(int i=4;i<=n;i++)
{
dp[i]=dp[i-2]+dp[i-3];
}
c=dp[n];
cout<<a<<" "<<b<<" "<<c<<endl;
}
return 0;
}