20182019-acmicpc-asia-nanjing-regional赛后整理

本文是20182019 ACM/ICPC亚洲区南京区域赛的赛后整理,详细介绍了各题目的题意和部分解题思路。包括Adrien和Austin的问题、锦标赛问题、樱桃和巧克力问题等,涉及数三角形、最小球覆盖、硬币反转等算法问题。作者分享了在比赛中的思考和遗憾,如在G题和E题上的失误,并提供了部分题目的解决方案,如Magic Potion问题使用网络流解决,Prime Game问题通过素因子计算子序列价值。
摘要由CSDN通过智能技术生成

20182019-acmicpc-asia-nanjing-regional 赛后整理

这次比赛中就a了三道题(a,i,j),但其实还有四道是可做题目。

这次比赛g题因为推错第4项和第5项导致整个过程GG,一直推错公式还以为自己很对。

E题是开关性质的一个题,也可以做,但是当时没看这道题,M题是最后一个小时才看的,没想起来让字符串s反转一下,当时也没报太大希望…赛后表示这道题不难(赛后一直还sb的认为自己正确的思路是错的,以为回文自动机+exkmp会有重复计算,实际上这是不可能),D题爬山就可以a了。

因为鄙人英语不太好,所以每次比赛也会把不会做的题目给翻一下,若发现有错误,指正不胜感激

PS: 时间2019-9-30,这个整理鸽了快一星期了…

比赛链接:传送门

Problem A. Adrien and Austin

题意:n个石子,每次只能取连续的1到k个石子,最优策略下谁输

思路:第一个人先取中间的几个,另一个人取的时候第一个人对称取即可,需要判断特判n=0时先手输和k=1时即可

#include<bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof(a))
using namespace std;
const int N=2e3+50;
int main()
{
   
    int n,k;
    cin>>n>>k;
    if(n==0||(k==1&&n%2==0)) puts("Austin");
    else puts("Adrien");
    return 0;
}

Problem B. Tournament

题意: 给你n个村庄的位置(这些村庄在一条线上),第一个村庄的位置是0。让你在这条直线上建立K个体育馆,问建立之后村民到体育馆的距离和最小是多少。(定义村民到体育馆的距离为该村民到最近的体育馆的距离

思路: 不会

Problem C. Cherry and Chocolate

题意:给出一颗树,有两个人,第一个人先从树上选个点染成粉红色,然后第二个人从树上选个点染成巧克力色,最后第一个人又从树上选一个点染成粉红色。如果树上某个点到粉红点的路径不经过巧克力色的点,第一个人就获得一个节点,第二个不想让第一个人获得多的节点,最优策略下第一个人可以获得多少节点

思路:不会

Problem D. Country Meow

题意: 求最小球覆盖

思路: 爬山每次往较远的点逼近就行。

ps:顺便偷了个三分套三分的模板

#include <bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
//typedef pair<int,int>  P;
const int N=105;
struct pnode{
   
double x,y,z;
pnode(){
   }
pnode(double x,double y,double z):x(x),y(y),z(z){
   }
}p[N];
double getdis(const pnode&a,const pnode &b)
{
   
    double dx=a.x-b.x,dy=a.y-b.y,dz=a.z-b.z;
    return dx*dx+dy*dy+dz*dz;
}
int main()
{
   
    int n;
    scanf("%d",&n);
    double ans=1e10;
    for(int i=1;i<=n;++i) scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z);
    double x=0,y=0,z=0;
    double L=2e5,desc=0.99;
    while(L>=1e-7)
    {
   
        //找到最远的点,然后移动部分距离
        pnode far;
        double d=0;
        for(int i=1;i<=n;++i)
        {
   
            double m=getdis(pnode(x,y,z),p[i]);
            if(m>d)
            {
   
                d=m;
                far=p[i];
            }
        }
        double dx=far.x-x,dy=far.y-y,dz=far.z-z;
        double m=sqrt(dx*dx+dy*dy+dz*dz);
        ans=min(ans,m);
        x+=L*dx/m;
        y+=L*dy/m;
        z+=L*dz/m;
        L*=desc;
    }
    printf("%.10f\n",ans);
    return 0;
}

Problem E. Eva and Euro coins

题意: 给你n个硬币的状态(0,1正反面),每次可以反转k个连续同状态的硬币,问A状态能否到达B状态

思路:模拟几次你会发现,从A状态反转后的任意一个状态C,两个状态不停的去掉连续的k个1或0后剩下的字符串相同,所以我们只需判断A状态和B状态去掉连续的K个1或0之后剩下的字符串是否相同即可。

据说这是个开关性质,但是目前我还不会证明。。。

#include <bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int N=1e6+10;
int k;
char e[N];
int d[N];
int work(char s[],int ls)//返回处理后的字符串的长度
{
   
    int top=0;
    e[0]=' ';
    d[0]=0;
    for(int i=0;i<ls;++i)
    {
   
        e[++top]=s[i];
        if(e[top]==e[top-1])
            d[top]=d[top-1]+1;
        else
            d[top]=1;
        if(d[top]==k)
        {
   
            top-=k;
        }
    }
    for(int i=0;i<top;++i)
        s[i]=e[i+1];
    s[top]=0;
    return top;
}
char s[N],t[N];
int main()
{
   
    int ls;
    scanf("%d%d",&ls,&k);
    scanf("%s%s",s,t);
    int ls1=work(s,ls);
    int ls2=work(t,ls);
    if(ls1==ls2&&strcmp(s,t)==0)
        puts("Yes");
    else
        puts("No");
    return 0;
}

Problem F. Frank

题意:给出一个图可能有重边,每次给出初始城市C0和旅行的列表,每天自己会从一个城市随机选一条边去另一个城市,从c0走的路线中包含旅行列表的序列的时停止,问期望的天数。

思路:不会

Problem G. Pyramid

题意:数三角形

思路:答案: ( n

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值