题解:
ans = sigma(1 - (1 - Pi/100)^ 2);
标程:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int N,p;
double ans=0.0;
scanf("%d",&N);
ans=N;
while(N--)
{
scanf("%d",&p);
p=100-p;
ans=ans-p*p*1.0/10000.0;
}
printf("%.3lf",ans);
return 0;
}
B可怜的非洲银
题解:模拟每个碎片按照顺序得到即可,注意每天先购买1个F碎片,输出有先后顺序
#include <stdio.h>
#include <stdlib.h>
int main()
{
int cnt[26];
char s[150];
int N,K,i,j,day=0,flag=0;
for(i=0;i<26;i++)cnt[i]=0;
scanf("%d%d",&N,&K);
for(i=0;i<N;i++)
{
scanf("%s",&s);
cnt['F'-'A']++;
for(j=0;s[j]!='\0';j++)
{
if(flag==1)
break;
cnt[s[j]-'A']++;
if(cnt['F'-'A']>=50){
printf("%d F",i+1);
flag=1;break;
}
if(cnt[s[j]-'A']>=50){
printf("%d %c",i+1,s[j]);
flag=1;break;
}
}
}
if(flag==0&&K>N)printf("AMNZ");
else if(flag==0)printf("Feizhou Yin");
return 0;
}
C简单的数学题
题解:
a * 10 + b - (b * 10 + a )是9的倍数 说明交换相邻数位之后 原数和新数的差是9的倍数,那你可以通过不断交换获得最小的数,即将各个位数从小到大排列后输出即可
#include <stdio.h>
#include <stdlib.h>
int main()
{
int cnt[10]={0};
char ans[1010];
char s[1010];
scanf("%s",&s);
int i,p=0;
for(i=0;s[i]!='\0';i++)
cnt[s[i]-'0']++;
for(i=0;i<10;i++)
{
while(cnt[i])
{
cnt[i]--;
ans[p++]=i+'0';
}
}
ans[p++]='\0';
printf("%s",ans);
return 0;
}
D 我想上厕所
题解:
三种情况0个人上错厕所 输出02个人上错厕所 选择两个方向最短的3个人上错厕所 推导公式:两个人之间有个间隔,总共有3个间隔,选取其中最短的2个
标程
#include<stdio.h>
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
int n,i,cnt,ans;
int a,p[5];
scanf("%d",&n);cnt=0;
for(i=1;i<=n;i++)
{
scanf("%d",&a);
if (a!=i)
{
cnt++;
p[cnt]=i;
}
}
if (cnt==0) ans=0;
if (cnt==2)
{
ans=min(p[2]-p[1],n-p[2]+p[1]);
ans=2*ans-1;
}
if (cnt==3)
{
ans=min(p[3]-p[1],n-(p[2]-p[1]));
ans=min(ans,n-(p[3]-p[2]));
ans=2*ans-2;
}
printf("%d\n",ans);
return 0;
}
E-Megumin的爆裂魔法
显然,n==1时,最小圆退化为一个点。
n==2时,最小圆半径为连接两点的线段长度的一半,圆心位于线段中点。
n==3时,若三点构成一个钝角三角形,则最小圆半径为三角形最长边长度的一半,圆心位于最长边中点。
若构成的三角形是锐角或直角三角形,则最小圆为其外接圆。
考虑如何求外接圆圆心:
任取三角形的两条边,作它们的垂直平分线,求交点即可。
但是在程序中如何实现?如果仅仅依靠高中的斜截式直线方程,我们需要讨论我们取的这两条边所在直线的斜率是否存在,是否为零,是否存在且非零这几种情况,在第一份标程中,命题人所给出的就是这样的做法。
该题的情况比较多,需要讨论全面,同时对实数的处理也是一项挑战。
在算法竞赛中,我们处理直线,一般用其上的一个点和一个方向向量,即参数式表示,这样可以避免分类讨论,比较容易求得垂直平分线和交点,请读者自行思考。
#include<math.h>
#define EPS 0.00000001
int n;
typedef struct {double x,y;}Point;
typedef Point Vector;
double sqr(double x){return x*x;}
double dis(Point a,Point b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}
Vector Minus (Point a,Point b){return (Vector){a.x-b.x,a.y-b.y};}
double dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;};
int check(Point a,Point b){
if(fabs(a.x-b.x)<EPS) return -1;
if(fabs(a.y-b.y)<EPS) return 1;
return 0;
}
Point a[3];
int main()
{
// freopen("09.in","r",stdin);
// freopen("09.out","w",stdout);
int i;
scanf("%d",&n);
for(i=0;i<n;++i) scanf("%lf%lf",&a[i].x,&a[i].y);
if(n==1) {printf("%.4f %.4f %.4f\n",0.0,a[0].x,a[0].y); return 0;}
if(n==2) {printf("%.4f %.4f %.4f\n",dis(a[0],a[1])*0.5,(a[0].x+a[1].x)*0.5,(a[0].y+a[1].y)*0.5); return 0;}
if(dot(Minus(a[1],a[0]),Minus(a[2],a[0]))<EPS) {printf("%.4f %.4f %.4f\n",dis(a[1],a[2])*0.5,(a[1].x+a[2].x)*0.5,(a[1].y+a[2].y)*0.5); return 0;}
else if(dot(Minus(a[1],a[2]),Minus(a[0],a[2]))<EPS) {printf("%.4f %.4f %.4f\n",dis(a[1],a[0])*0.5,(a[1].x+a[0].x)*0.5,(a[1].y+a[0].y)*0.5); return 0;}
else if(dot(Minus(a[0],a[1]),Minus(a[2],a[1]))<EPS) {printf("%.4f %.4f %.4f\n",dis(a[0],a[2])*0.5,(a[0].x+a[2].x)*0.5,(a[0].y+a[2].y)*0.5); return 0;}
int flag1=check(a[0],a[1]),flag2=check(a[0],a[2]);
if(flag1!=0 && flag2!=0){
Point tmp=a[0]; a[0]=a[1]; a[1]=tmp;
flag2=check(a[0],a[2]);
}
if(flag2!=0){
Point tmp=a[1]; a[1]=a[2]; a[2]=tmp;
int tm2=flag1; flag1=flag2; flag2=tm2;
}//line(a[0],a[1])为特殊或一般;line(a[0],a[2])为一般
double k2=(a[2].y-a[0].y)/(a[2].x-a[0].x);
double b2=a[0].y-a[0].x*k2;
double k4=(-1.0)/k2;
Point mp2=(Point){(a[0].x+a[2].x)*0.5,(a[0].y+a[2].y)*0.5};
double b4=mp2.y-mp2.x*k4;
if(flag1==-1){
Point ap; ap.y=(a[0].y+a[1].y)*0.5;
ap.x=(ap.y-b4)/k4;
printf("%.4f %.4f %.4f\n",dis(ap,a[0]),ap.x,ap.y);
}
else if(flag1==1){
Point ap; ap.x=(a[0].x+a[1].x)*0.5;
ap.y=k4*ap.x+b4;
printf("%.4f %.4f %.4f\n",dis(ap,a[0]),ap.x,ap.y);
}
else/*flag1==0*/{
double k1=(a[1].y-a[0].y)/(a[1].x-a[0].x);
double b1=a[0].y-a[0].x*k1;
double k3=(-1.0)/k1;
Point mp1=(Point){(a[0].x+a[1].x)*0.5,(a[0].y+a[1].y)*0.5};
double b3=mp1.y-mp1.x*k3;
Point ap; ap.x=(b4-b3)/(k3-k4); ap.y=k3*ap.x+b3;
printf("%.4f %.4f %.4f\n",dis(ap,a[0]),ap.x,ap.y);
}
return 0;
}
设三角形三个顶点分别为(x1,y1),(x2,y2),(x3,y3),待求的圆心为(x,y)。
则显然有以下方程组成立
(x-x1)^2+(y-y1)^2 = (x-x2)^2+(y-y2)^2 = (x-x3)^2+(y-y3)^2
化简为
{2*(x2-x1)*x+2*(y2-y1)*y = -x1^2-y1^2+x2^2+y2^2
{
{2*(x3-x1)*x+2*(y3-y1)*y = -x1^2-y1^2+x3^2+y3^2
该二元一次方程组可以用克拉默法则方便求解。
这种做法不需要讨论三条边的种种位置关系,代码也比较短,在第二份标程中给出。
#include<stdio.h>
#include<math.h>
#define EPS 0.00000001
int n;
typedef struct {double x,y;}Point;
typedef Point Vector;
double sqr(double x){return x*x;}
double dis(Point a,Point b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}
Vector Minus (Point a,Point b){return (Vector){a.x-b.x,a.y-b.y};}
double dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;};
Point a[3];
int main()
{
// freopen("01.in","r",stdin);
// freopen("09.out","w",stdout);
int i;
scanf("%d",&n);
for(i=0;i<n;++i) scanf("%lf%lf",&a[i].x,&a[i].y);
if(n==1) {printf("%.4f %.4f %.4f\n",0.0,a[0].x,a[0].y); return 0;}
if(n==2) {printf("%.4f %.4f %.4f\n",dis(a[0],a[1])*0.5,(a[0].x+a[1].x)*0.5,(a[0].y+a[1].y)*0.5); return 0;}
if(dot(Minus(a[1],a[0]),Minus(a[2],a[0]))<EPS) {printf("%.4f %.4f %.4f\n",dis(a[1],a[2])*0.5,(a[1].x+a[2].x)*0.5,(a[1].y+a[2].y)*0.5); return 0;}
else if(dot(Minus(a[1],a[2]),Minus(a[0],a[2]))<EPS) {printf("%.4f %.4f %.4f\n",dis(a[1],a[0])*0.5,(a[1].x+a[0].x)*0.5,(a[1].y+a[0].y)*0.5); return 0;}
else if(dot(Minus(a[0],a[1]),Minus(a[2],a[1]))<EPS) {printf("%.4f %.4f %.4f\n",dis(a[0],a[2])*0.5,(a[0].x+a[2].x)*0.5,(a[0].y+a[2].y)*0.5); return 0;}
double b[3],A[3][3];
A[1][1]=2.0*(a[1].x-a[0].x);
A[1][2]=2.0*(a[1].y-a[0].y);
b[1]=-a[0].x*a[0].x-a[0].y*a[0].y+a[1].x*a[1].x+a[1].y*a[1].y;
A[2][1]=2.0*(a[2].x-a[0].x);
A[2][2]=2.0*(a[2].y-a[0].y);
b[2]=-a[0].x*a[0].x-a[0].y*a[0].y+a[2].x*a[2].x+a[2].y*a[2].y;
double tmp=A[1][1]*A[2][2]-A[1][2]*A[2][1];
double tmp1=b[1]*A[2][2]-A[1][2]*b[2];
double tmp2=A[1][1]*b[2]-b[1]*A[2][1];
Point ans;
ans.x=tmp1/tmp;
ans.y=tmp2/tmp;
printf("%.4f %.4f %.4f\n",dis(ans,a[0]),ans.x,ans.y);
return 0;
}
感谢大家参加本场趣味赛,趣味赛评奖结果我们会在群内公布,接下来还有两场更为精彩的比赛,欢迎大家参加!