您的位置:首页 > 其它

2017年多校联合训练 第六场(福州大学)

2017-08-14 19:43 274 查看
官方题解

1002 Mindis

hdoj6097题目链接

几何方法:

将点P关于圆O的反演点记作P',由定义得OP*OP'=r2,则△ODP~△ODP',相似比为OP:R,点Q同理

当反演点的连线与圆有交点时,min(DP+DQ)转化为min(DP'+DQ')*相似比

否则D即为△OPQ中从点O出发的角平分线(等腰三角形三线合一)与圆的交点,计算DP+DQ

代码种用复数形式记录点,abs( )返回模值,norm( )返回模的平方

#include<bits/stdc++.h>
using namespace std;
typedef complex<double> V;
int main()
{
int t;
scanf("%d",&t);
while(t--){
double r,x,y,s;
scanf("%lf",&r);
scanf("%lf%lf",&x,&y);
V p=V(x,y);
scanf("%lf%lf",&x,&y);
V q=V(x,y);
if(p==q) s=2*(r-abs(p)); //特殊情况:两点重合
else{
V pp=p*r*r/norm(p);
V qq=q*r*r/norm(q);
if(norm(pp)-norm(pp-qq)/4<=r*r) s=abs(pp-qq)*abs(p)/r; //△OP'Q'的高小于等于R,则反演点连线与圆O有交点
else{
V mid=p+q;
if(p==-q) mid=V(-p.imag(),p.real());
mid=mid/abs(mid)*r; //mid表示角平分线与圆的交点
s=2*abs(mid-p);
}
}
printf("%.7f\n",s);
}
}


1003 Inversion

hdoj6098题目链接

优雅的暴力做法:

排序后找到下标不能整除当前下标的最大值

#include<bits/stdc++.h>
using namespace std;
struct node
{
int v,p;
bool operator < (const node& x) const { return v>x.v; }
}a[100005];
int main()
{
int t,n,i,j;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(i=1;i<=n;i++) scanf("%d",&a[i].v),a[i].p=i;
sort(a+1,a+1+n);
for(i=2;i<=n;i++){
for(j=1;j<=n&&a[j].p%i==0;j++);
printf("%d%c",a[j].v,i==n?'\n':' ');
}
}
}


1008 Kirinriki

hdoj6103题目链接

回文串,枚举对称轴,双指针维护

#include<bits/stdc++.h>
using namespace std;
int main()
{
int t,m,len,ans,cnt,sum,l,x,r,y,i;
char s[5005];
scanf("%d",&t);
while(t--){
scanf("%d%s",&m,s+1);
len=strlen(s+1);
ans=0;
for(i=2;i<len;i++){ //以下标为i的字符为对称轴
l=x=i-1,r=y=i+1;
cnt=sum=0;
while(l&&r<=len){
sum+=abs(s[l]-s[r]),cnt++;
if(sum<=m) ans=max(ans,cnt);
else{
while(sum>m){
sum-=abs(s[x]-s[y]);
x--,y++;
cnt--;
}
}
l--,r++;
}
}
for(i=1;i<len;i++){ //以下标为i的字符右侧间隙为对称轴
l=x=i,r=y=i+1;
cnt=sum=0;
while(l&&r<=len){
sum+=abs(s[l]-s[r]),cnt++;
if(sum<=m
4000
) ans=max(ans,cnt);
else{
while(sum>m){
sum-=abs(s[x]-s[y]);
x--,y++;
cnt--;
}
}
l--,r++;
}
}
printf("%d\n",ans);
}
}


1010 Gameia

hdoj6105题目链接

//比赛最后1h开了这题,菜鸡QYQ和Dsaitou玩了好几把,一直没啥头绪。只见lza11111一眼看穿规律,1A,撒花

如果Bob能把这棵树分成若干两个一组的点对,那么Bob取得胜利,否则Alice获胜:

代码中首先特判了结点个数为奇,Bob超能力使用次数不够的情况,都是Alice获胜。

然后暴力枚举叶子结点,若存在有多个儿子节点时叶子节点的情况,那么Alice获胜。

#include<bits/stdc++.h>
using namespace std;
#define N 505
int main()
{
int t,n,k,d
,f
,i,j,fg;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
memset(d,0,sizeof(d));
for(i=2;i<=n;i++) scanf("%d",&f[i]),d[i]++,d[f[i]]++;
if(n&1||k<n/2-1) { puts("Alice");continue; }
for(fg=0,i=2;i<=n;i++)if(d[i]==1){
for(j=i+1;j<=n;j++)if(f[i]==f[j]&&d[j]==1) { fg=1;break; }
}
puts(fg?"Alice":"Bob");
}
}


1011 Classes

hdoj6106题目链接

签到快乐

#include<bits/stdc++.h>
using namespace std;
int main()
{
int t,n,mx,a,b,c,ab,bc,ac,abc;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
mx=0;
while(n--){
scanf("%d%d%d%d%d%d%d",&a,&b,&c,&ab,&bc,&ac,&abc);
ab-=abc,bc-=abc,ac-=abc;
if(ab<0||bc<0||ac<0) continue;
a-=ab+ac+abc,b-=bc+ab+abc,c-=bc+ac+abc;
if(a<0||b<0||c<0) continue;
mx=max(mx,a+b+c+ab+bc+ac+abc);
}
printf("%d\n",mx);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: