湖南大学第十六届程序设计竞赛(重现赛)
A题
先判断三个点是否能构成一个三角形,只有三点在同一直线上是不行的,然后用余弦定理的推论可以判断是什么类型的三角形
#include<bits/stdc++.h>
#define maxn 1000000000 + 7
using namespace std;
typedef long long ll;
double poi[5][5];
int main()
{
ll n;
cin>>n;
double x,y,z;
while(n--)
{
for(int i=1;i<=3;i++)
{
cin>>poi[i][1]>>poi[i][2];
}
x=(poi[1][1]-poi[2][1])*(poi[1][1]-poi[2][1])+(poi[1][2]-poi[2][2])*(poi[1][2]-poi[2][2]);
y=(poi[3][1]-poi[2][1])*(poi[3][1]-poi[2][1])+(poi[3][2]-poi[2][2])*(poi[3][2]-poi[2][2]);
z=(poi[1][1]-poi[3][1])*(poi[1][1]-poi[3][1])+(poi[1][2]-poi[3][2])*(poi[1][2]-poi[3][2]);
double t;
if(x>z)
{
t=z;
z=x;
x=t;
}
if(y>z)
{
t=y;
y=z;
z=t;
}
if(x>y)
{
t=x;
x=y;
y=t;
}
double a,b,c;
a=sqrt(x*1.00);
b=sqrt(y*1.00);
c=sqrt(z*1.00);
if(a+b<=c||a+c<=b||c+b<=a)cout<<"invalid\n";
else{
if(x+y==z)cout<<"right\n";
else if(x+y>z)cout<<"acute\n";
else cout<<"obtuse\n";
}
}
return 0;
}D题
找规律,对于n个窗口,m个人,结果是1+(m-1)/n,其实也可以理解为每个人有1/n的概率站在你前面,然后共有m个人,除你之外就是(m-1)个人。
#include<bits/stdc++.h>
#define maxn 1000000000 + 7
using namespace std;
typedef long long ll;
int main()
{
ll m,n;
scanf("%d%d",&n,&m);
printf("%.8lf",1.00000000+(m-1.00000000)/n*1.00000000);
return 0;
}F题
签到题,高精度加法。
#include<bits/stdc++.h>
#define maxn 1000000000 + 7
using namespace std;
typedef long long ll;
int s[200];
int main()
{
string a,b;
int c;
cin>>a>>b>>c;
int carry=0;
int l1,l2;
l1=a.length();
l2=b.length();
int i;
int j=50;
s[j]=a[l1-1]-'0'+b[l1-1]-'0'+c;
carry=s[j]/10;
s[j]%=10;
j--;
for(i=l1-2;i>=0;i--)
{
s[j]=a[i]-'0'+b[i]-'0'+carry;
carry=s[j]/10;
s[j]%=10;
j--;
}
if(carry)s[j]=carry;
for(;j<=50;j++)cout<<s[j];
return 0;
}G题
其实输出只有三种0,1,2。两个字符串完全相同那么结果就是0,两个字符串部分相同,但是缺少前面一段或者后面一段(必须是连续的一段)那么答案是1,其他的全是2。所以我们只要分别从前往后和从后往前匹配一遍字符串即可
#include<bits/stdc++.h>
#define maxn 1000000000 + 7
using namespace std;
typedef long long ll;
string s,t;
int main()
{
cin>>s>>t;
ll l1,l2;
l1=s.length();
l2=t.length();
ll i,j;
i=j=0;
ll sum=0;
while(i<l1&&j<l1)
{
if(s[i]==t[j])
{
i++;
j++;
sum++;
}
else break;
}
i=l1-1;
j=l2-1;
while(i>=0&&j>=0)
{
if(s[i]==t[j])
{
i--;
j--;
sum++;
}
else break;
}
if(sum==2*l1&&l1==l2)cout<<0<<'\n';
else if(sum==l1||l2==sum)cout<<1<<'\n';
else cout<<2<<'\n';
return 0;
}I题
题目只给了我们两个小球,因此我们只有两次失败的机会,当我们尝试失败了,我们只能从保证扔下去不会碎的楼层开始,从下往上尝试,假设我们最差的情况下最少需要扔x次,那么假如第一次失败了,我们就要从下往上挨个楼层尝试,那么就是第一次在x楼扔碎了第一颗球,此时拿第二颗球从下往上尝试刚好是x次,以此类推,如果成功了,我们第二次就要从2x-1层往下扔,为了保证不管是成功还是失败,结果都是要x次,以此类推,最高的楼层就是(x+1)x/2,当(x+1)*x/2>=n时,满足不等式的最小正整数x即为本题答案,进一步化简可以得到O(1)的表达式ans =ceil((sqrt(1 + 8 * n) - 1) / 2);
#include<bits/stdc++.h>
#define maxn 1000000000 + 7
using namespace std;
typedef long long ll;
ll a[1000000];
int main()
{
ll t,n;
cin>>t;
while(t--)
{
cin>>n;
long long ans =ceil((sqrt(1 + 8 * n) - 1) / 2);
cout<<ans<<endl;
}
return 0;
}


京公网安备 11010502036488号