第一题:
题目意思:我过生日请了f 个朋友来参加我的生日party,m个蛋糕,我要把它平均分给每个人(包括我),并且每个人只能从一块蛋糕得到自己的那一份,并且分得的蛋糕大小要一样,形状可以不一样,每块蛋糕都是圆柱,高度一样。
此题是一个二分题,下限是用最大的分,上限是sum/f+1。中间值是m,当cnt+=cnt+=(int)floor(p[i]/m);cnt<f+1,则r=m;否则l=m;二分的结束条件是(l+0.00001)。
第十六题:
思路:
这个题是叫我们求最小值,那么很明显对于函数求最值,最简单的方法就是求导
我们队f(x)求导之后得到:f'(x)=42*x^6+48*x^5+21*x*x+10x-y
很明显,当f'(x)=0时取得最值,然后由于定义域x属于[0,100]那么可以推断,f'(x)=0时
f(x)有最小值。
我们可以利用二分算法去计算f'(x)=0时x为多少(注意f'(x)是单调递增的)
计算出x之后再代入原函数解出最小值即可。
#include<stdio.h>
#include<math.h>
double df(double x)
{
return 42*pow(x,6)+48*pow(x,5)+21*x*x+10*x;
}
double f(double x,double y)
{
return 6*pow(x,7)+8*pow(x,6)+7*pow(x,3)+5*x*x-y*x;
}
int main()
{
int t,i;
double y,left,right,mid;
scanf("%d",&t);
while(t--)
{
scanf("%lf",&y);
left=0,right=100;
for(i=1;i<=100;i++)
{
mid=(left+right)/2;
if(df(mid)>y)
right=mid;
else
left=mid;
}
printf("%.4lf\n",f(mid,y));
}
return 0;
}
解题思路:
1.建立函数f(x)=8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 - Y,将问题转换为在区间[0,100]上用二分法求方程f(x)=0的根,注意控制精度exp
#include<iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include<cmath>
#define maxn 100010
#define eps 1e-6
using namespace std;
double y;
double f(double x)
{
return 8*pow(x,4)+7*pow(x,3)+2*pow(x,2)+3*x+6-y;
}
double bsearch()
{
double x=0,y=100;
double m;
while(y-x>=eps)
{
m=(y+x)/2;
if(f(m)>0) y=m;else x=m;
}
return m;
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>y;
if(f(0)*f(100)>0)
cout<<"No solution!"<<endl;
else
{
printf("%.4lf\n",bsearch());
}
}
return 0;
}
练习赛第二题:
求出所有数中的最大值,就是简单的数塔问题!
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[444][444];
int main()
{
int n,i,j;
while(cin>>n)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++)
{
cin>>a[i][j];
}
}
for(i=n-1;i>0;i--)
{
for(j=1;j<=i;j++)
{
a[i][j]+=max(a[i+1][j],a[i+1][j+1]);
}
}
cout<<a[1][1]<<endl;
}
return 0;
}
练习赛第一题:
#include <iostream>
using namespace std;
char s[][10]={"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};
bool pan(int y)
{
if(y%4==0&&y%4!=100||y%400==0)
return true;
else
return false;
}
int getday(int y, int m)
{
if(m==1||m==3||m==5||m==7||m==8||m==10||m==12)
return 31;
else
if(m==4||m==6||m==9||m==11)
return 30;
else
if(pan(y))
return 29;
else
return 28;
}
int main()
{
int y,m,d,n,t;
cin>>y>>m>>d;
n=d-1;
for(int i=1;i<m;i++)
n+=getday(y,i);
t=y+(y-1)/400-(y-1)/100+(y-1)/4;
t=t%7;
t=(t+n)%7;
cout<<s[t]<<endl;
return 0;
}
练习赛第三题:
用dfs算出每个连通块的大小即可
#include <iostream>
#include <queue>
using namespace std;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
int w,h;
char g[1200][1220];
struct point{int x,y;};
int fun(const point &t,int &sum)
{
int x,y,a,b,i;
x=t.x,y=t.y;
point tmp;
if (g[x][y]=='.')
return 0;
g[x][y]='.';
sum++;
for (i=0;i<4;i++)
{
a=x+dx[i];b=y+dy[i];
if (a<0||b<0||a>=h||b>=w)
continue;
tmp.x=a,tmp.y=b;
fun(tmp,sum);
}
return 0;
}
int main()
{
cin>>w>>h;
int i,j,sum,max=0;
point tmp;
for (i=0;i<h;i++)
cin>>g[i];
for (i=0;i<h;i++)
for (j=0;j<w;j++)
{
sum=0;
tmp.x=i;tmp.y=j;
fun(tmp,sum);
if (max<sum)
max=sum;
}
cout<<max<<endl;
return 0;
}
第四题:
题意:
求给出数据含有最大质数的数,如:36 38 40 42 即19为38的最大质数,也是4个数中最大的质数。
所以输出包含最大质数的数38,还要题目最后说如果有多个,要输出最前面的那个数。
思路:
先打表出所有的素数,然后再寻找即可。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 20017;
int s[MAXN];
int main()
{
int n,m;
memset(s,0,sizeof(s));
s[1]=1;
for(int i = 2; i < MAXN; i++)
{
if(s[i] == 0)
for(int j = i; j < MAXN; j+=i)
{
s[j]=i;
}
}
while(cin>>n)
{
int ans;
int maxx = -1;
for(int i = 0; i < n; i++)
{
cin>>m;
if(s[m] > maxx)
{
maxx = s[m];
ans = m;
}
}
cout<<ans<<endl;
}
return 0;
}