今天总结几道在冬令营训练的题目
第一题(初等几何)
分析:
根据题意我们容易知道的是在所输入的四个点的坐标中,有可能会有两个点是重复的,所以需要先判断一下重复的是哪两个点;然后,因为是平行四边形,根据简单的平面几何知识,设一个平行四边形的四个顶点的逆时针顺序依次为a,b,c,d,则a.x-b.x=d.x-c.x, a.y-b.y=d.y-c.y,这样我们就能很容易的对第四个点的坐标进行确定。
#include<iostream>
using namespace std;
typedef struct{
double x,y;
}point;
int main(){
point a,b,c,d,e;
while(~scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y)){
scanf("%lf%lf%lf%lf",&c.x,&c.y,&d.x,&d.y);
if(a.x==c.x&&a.y==c.y)swap(a,b);//第一种情况
if(a.x==d.x&&a.y==d.y){
//第二种情况
swap(a,b);
swap(c,d);
}
if(b.x==d.x&&b.y==d.y)swap(c,d);//第三种情况
e.x=a.x+d.x-c.x;//第四种,也是我们集中情况调整后的状态
e.y=a.y+d.y-c.y;
printf("%.3lf %.3lf\n",e.x,e.y);
}
return 0;
}
第二题(初等几何)
对于此题,让我们求任意非共线的三点的外接圆的周长,根据初等几何的知识,可以根据正弦定理求得外接圆直径,设该三角形三条边长分别为a,b,c,而三角形内任意一角的sin值我们可以根据三角形面积公式s=absin∠ab/2来确定,再有,根据海伦公式s=√p*(p-a)(p-b)(p-c),p=(a+b+c)/2,结合以上公式,即可解出所求外接圆的周长。
代码如下:
#include<stdio.h>
#include<math.h>
#define PI 3.141592653589793
double length(double x1,double y1,double x2,double y2){
double side;
side=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
return side;
}
double triangle(double side1,double side2,double side3){
double p=(side1+side2+side3)/2;
double area=sqrt(p*(p-side1)*(p-side2)*(p-side3));
return area;
}
double diameter(double s,double a,double b,double c){
double diam;
diam=a*b*c/2/s;
return diam;
}
int main(){
double x1,y1,x2,y2,x3,y3,side1,side2,side3,s,d;
while((scanf("%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3))!=EOF){
side1=length(x1,y1,x2,y2);
side2=length(x1,y1,x3,y3);
side3=length(x2,y2,x3,y3);
s=triangle(side1,side2,side3);
d=diameter(s,side1,side2,side3);
printf("%.2lf\n",PI*d);
}
return 0;
}
第三题
对于该题,因为出现’[‘和’]‘后,对输出字符串中的字符顺序会有影响,所以如果我们把整个字符串中的每个元素放到线性链表中,借助指针能更好地解决问题,我们可以使用一个一维数组next来模拟链表中的指针next,即next[0]不存放元素,输入的第一个字符的下一个字符为第二个字符,next[1]=2,以此类推,来借助数组模拟指针。我们可以借助一个变量cur来表示光标所在位置,一个变量last来表示所输出的字符串的最后末尾位置,cur变量的值意义为下一个字符位置在光标右侧,若遇到’[’,则将cur=0;若遇到’]’。则将cur=last,
cur和last需要及时更新。
#include<bits/stdc++.h>
using namespace std;
#define maxl 100905
int main(){
char s[maxl];
while(~scanf("%s",s+1)){
int Next[maxl]={
0};
int cur=0,last=0;
for(int i=1;s[i];i++){
if(s[i]=='[')cur=0;//光标去最前面
else if(s[i]==']')cur=last;//光标去最后面
else{
Next[i]=Next[cur];//链表插入操作
Next[cur]=i;
if(cur==last)last=i;//更新last
cur=i;//更新cur
}
}
for(int i=Next[0];i!=0;i=Next[i])//输出
if(s[i]!='['&&s[i]!=']')printf("%c",s[i]);
printf("\n");
}
return 0;
}