2018-2019 ACM-ICPC, Asia Nanjing Regional Contest

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_32872703/article/details/85220659

施工中(8/13)

题目链接:http://codeforces.com/gym/101981

A.Adrien and Austin

队友写的,没看题

代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+5;
int n,k;
void solve()
{
    int flag=1;
    if(n==0)
        flag=0;
    if(k==1&&n%2==0)
        flag=0;
    if(flag)
    {
        printf("Adrien\n");
    }
    else
    {
        printf("Austin\n");
    }
}
int main()
{
    while(~scanf("%d%d",&n,&k))
    {
        solve();
    }
    return 0;
}

D.Country Meow

最小球覆盖板题

代码:

#include<bits/stdc++.h>
const int MAXN=105;
const double eps=1e-8;
struct Tpoint
{
    double x,y,z;
};
int npoint,nouter;
Tpoint pt[MAXN],outer[4],res;
double radius,tmp;
inline double dist(Tpoint p1,Tpoint p2)
{
    double dx=p1.x-p2.x,dy=p1.y-p2.y,dz=p1.z-p2.z;
    return (dx*dx+dy*dy+dz*dz);
}
inline double dot(Tpoint p1,Tpoint p2)
{
    return p1.x*p2.x+p1.y*p2.y+p1.z*p2.z;
}
void ball()
{
    Tpoint q[3];double m[3][3],sol[3],L[3],det;
    res.x=res.y=res.z=radius=0;
    switch(nouter)
    {
        case 1: res=outer[0];break;
        case 2:
            res.x=(outer[0].x+outer[1].x)/2;
            res.y=(outer[0].y+outer[1].y)/2;
            res.z=(outer[0].z+outer[1].z)/2;
            radius=dist(res,outer[0]);
            break;
        case 3:
            for(int i=0;i<2;i++)
            {
                q[i].x=outer[i+1].x-outer[0].x;
                q[i].y=outer[i+1].y-outer[0].y;
                q[i].z=outer[i+1].z-outer[0].z;
            }
            for(int i=0;i<2;i++)
            {
                for(int j=0;j<2;j++)
                {
                    m[i][j]=dot(q[i],q[j])*2;
                }
            }
            for(int i=0;i<2;i++)
            {
                sol[i]=dot(q[i],q[i]);
            }
            if(fabs(det=m[0][0]*m[1][1]-m[0][1]*m[1][0])<eps)
                return ;
            L[0]=(sol[0]*m[1][1]-sol[1]*m[0][1])/det;
            L[1]=(sol[1]*m[0][0]-sol[0]*m[1][0])/det;
            res.x=outer[0].x+q[0].x*L[0]+q[1].x*L[1];
            res.y=outer[0].y+q[0].y*L[0]+q[1].y*L[1];
            res.z=outer[0].z+q[0].z*L[0]+q[1].z*L[1];
            radius=dist(res,outer[0]);
            break;
        case 4:
            for(int i=0;i<3;i++)
            {
                q[i].x=outer[i+1].x-outer[0].x;
                q[i].y=outer[i+1].y-outer[0].y;
                q[i].z=outer[i+1].z-outer[0].z;
                sol[i]=dot(q[i],q[i]);
            }
            for(int i=0;i<3;i++)
            {
                for(int j=0;j<3;j++)
                {
                    m[i][j]=dot(q[i],q[j])*2;
                }
            }
            det=m[0][0]*m[1][1]*m[2][2]
            +m[0][1]*m[1][2]*m[2][0]
            +m[0][2]*m[2][1]*m[1][0]
            -m[0][2]*m[1][1]*m[2][0]
            -m[0][1]*m[1][0]*m[2][2]
            -m[0][0]*m[1][2]*m[2][1];
            if(fabs(det)<eps) return ;
            for(int j=0;j<3;j++)
            {
                for(int i=0;i<3;i++)
                {
                    m[i][j]=sol[i];
                }
                L[j]=(m[0][0]*m[1][1]*m[2][2]
                +m[0][1]*m[1][2]*m[2][0]
                +m[0][2]*m[2][1]*m[1][0]
                -m[0][2]*m[1][1]*m[2][0]
                -m[0][1]*m[1][0]*m[2][2]
                -m[0][0]*m[1][2]*m[2][1])/det;
                for(int i=0;i<3;i++)
                {
                    m[i][j]=dot(q[i],q[j])*2;
                }
            }
            res=outer[0];
            for(int i=0;i<3;i++)
            {
                res.x+=q[i].x*L[i];
                res.y+=q[i].y*L[i];
                res.z+=q[i].z*L[i];
            }
            radius=dist(res,outer[0]);
    }
}
void minball(int n)
{
    ball();
    if(nouter<4)
    {
        for(int i=0;i<n;i++)
        {
            if(dist(res,pt[i])-radius>eps)
            {
                outer[nouter]=pt[i];
                ++nouter;
                minball(i);
                --nouter;
            }
            if(i>0)
            {
                Tpoint Tt=pt[i];
                memmove(&pt[1],&pt[0],sizeof(Tpoint)*i);
                pt[0]=Tt;
            }
        }
    }
}
double smallest_ball()
{
    radius=-1;
    for(int i=0;i<npoint;i++)
    {
        if(dist(res,pt[i])-radius>eps)
        {
            nouter=1;
            outer[0]=pt[i];
            minball(i);
        }
    }
    return sqrt(radius);
}
int main()
{
    scanf("%d",&npoint);
    for(int i=0;i<npoint;i++)
        scanf("%lf%lf%lf",&pt[i].x,&pt[i].y,&pt[i].z);
    double res=smallest_ball();
    printf("%.10lf\n",res);
}

E.Eva and Euro coins

参考https://blog.csdn.net/sinat_32872703/article/details/84233142

代码:

#include<bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int MAXN=1e6+5;
int n,k;
char s[MAXN],t[MAXN];
int st[MAXN],sz[MAXN];
string doit(char x[])
{
	if(k==1) return "";
	int len=0;
	for(int i=1;i<=n;i++)
	{
		if(len&&st[len]==x[i])
		{
			sz[len]++;
			if(sz[len]==k)
				len--;
		}
		else
		{
			len++;
			st[len]=x[i];
			sz[len]=1;
		}
	}
	string ret="";
	for(int i=1;i<=len;i++)
	{
		for(int j=1;j<=sz[i];j++)
			ret+=st[i];
	}
	return ret;
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	scanf("%d%d",&n,&k);
	scanf("%s",s+1);
	scanf("%s",t+1);
	string A=doit(s);
	string B=doit(t);
	if(A==B) puts("Yes");
	else puts("No");
	return 0;
}

G.Pyramid

找了个麻烦的规律。。。被我们卡过去了

代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+5;
const int MOD=1e9+7;
typedef long long ll;
struct node
{
    int x,id;
    bool operator < (const node &o)const
    {
        return x<o.x;
    }
}sv[MAXN];
void add(int &a,int b)
{
    a=((a+b)%MOD+MOD)%MOD;
}
void mul(int &a,int b)
{
    a=1LL*a*b%MOD;
}
struct Matrix
{
    int b[5][5];
    Matrix(){memset(b,00,sizeof(b));}
    Matrix operator *(const Matrix &o) const
    {
        Matrix ret;
        for(int i=0;i<5;i++)
        {
            for(int j=0;j<5;j++)
            {
                for(int k=0;k<5;k++)
                {
                    int now=b[i][k];
                    mul(now,o.b[k][j]);
                    add(ret.b[i][j],now);
                }
            }
        }
        return ret;
    }
    Matrix operator -(const Matrix &o) const
    {
        Matrix ret;
        for(int i=0;i<5;i++)
        {
            for(int j=0;j<1;j++)
            {
                for(int k=0;k<5;k++)
                {
                    int now=b[i][k];
                    mul(now,o.b[k][j]);
                    add(ret.b[i][j],now);
                }
            }
        }
        return ret;
    }
    void init()
    {
        b[0][0]=3;b[0][1]=-3;b[0][2]=1;b[0][3]=1;b[0][4]=0;
        b[1][0]=1;b[1][1]=0;b[1][2]=0;b[1][3]=0;b[1][4]=0;
        b[2][0]=0;b[2][1]=1;b[2][2]=0;b[2][3]=0;b[2][4]=0;
        b[3][0]=0;b[3][1]=0;b[3][2]=0;b[3][3]=1;b[3][4]=1;
        b[4][0]=0;b[4][1]=0;b[4][2]=0;b[4][3]=0;b[4][4]=1;
    }
}p[35];
Matrix qpow(Matrix b,int o)
{
    for(int i=30;i>=0;i--)
    {
        if((o>>i)&1)
            b=p[i]-b;
    }
    return b;
}
int ans[MAXN];
inline char nc()
{
	static char buf[100000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void rea(int &x)
{
	char c=nc();x=0;
	for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
int main()
{
    //freopen("in.txt","r",stdin);
    int T;
    //scanf("%d",&T);
    rea(T);
    for(int i=1;i<=T;i++)
    {
        //scanf("%d",&sv[i].x);
        rea(sv[i].x);
        sv[i].id=i;
    }
    Matrix b;
    p[0].init();
    for(int i=1;i<=30;i++)
    {
        p[i]=p[i-1]*p[i-1];
    }
    b.b[0][0]=15;b.b[1][0]=5;b.b[2][0]=1;b.b[3][0]=4;b.b[4][0]=1;
    sort(sv+1,sv+1+T);
    sv[0].x=3;
    for(int i=1;i<=T;i++)
    {
        int id=sv[i].id;
        if(sv[i].x==1) ans[id]=1;
        else if(sv[i].x==2) ans[id]=5;
        else if(sv[i].x==3) ans[id]=15;
        else
        {
            if(sv[i-1].x<=3) sv[i-1].x=3;
            int det=sv[i].x-sv[i-1].x;
            b=qpow(b,det);
            ans[id]=b.b[0][0];
        }
    }
    for(int i=1;i<=T;i++)
        printf("%d\n",(ans[i]+MOD)%MOD);
}

I.Magic Potion

网络流裸题

代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=505*2;
const int MAXM=1e6+5;
const int INF=0x3f3f3f3f;
typedef long long ll;
namespace DINIC
{
    struct Edge
    {
        int u,v,cap,nxt;
        Edge(){}
        Edge(int _u,int _v,int _cap,int _nxt):u(_u),v(_v),cap(_cap),nxt(_nxt){}
    }E[MAXM];
    int head[MAXN],dis[MAXN],vis[MAXN];
    int tol;
    void init()
    {
        tol=0;
        memset(head,-1,sizeof(head));
    }
    void addedge(int u,int v,int cap)
    {
        E[tol]=Edge(u,v,cap,head[u]);
        head[u]=tol++;
        E[tol]=Edge(v,u,0,head[v]);
        head[v]=tol++;
    }
    bool BFS(int S,int T)
    {
        queue<int> q;
        q.push(S);
        memset(dis,0x3f,sizeof(dis));
        dis[S]=0;
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=head[x];~i;i=E[i].nxt)
            {
                if(E[i].cap>0&&dis[E[i].v]==INF)
                {
                    dis[E[i].v]=dis[x]+1;
                    if(E[i].v==T)
                        return true;
                    q.push(E[i].v);
                }
            }
        }
        return dis[T]<INF;
    }
    int dfs(int x,int maxflow,int T)
    {
        if(x==T||maxflow<=0)
            return maxflow;
        int ret=0;
        for(int &i=vis[x];~i;i=E[i].nxt)
        {
            if(dis[E[i].v]==dis[x]+1&&E[i].cap>0)
            {
                int flow=dfs(E[i].v,min(maxflow,E[i].cap),T);
                if(flow)
                {
                    ret+=flow;
                    maxflow-=flow;
                    E[i].cap-=flow;
                    E[i^1].cap+=flow;
                }
                if(maxflow==0)
                    break;
            }
        }
        return ret;
    }
    ll dinic(int S,int T,int N)
    {
        ll ans=0;
        while(BFS(S,T))
        {
            int flow;
            for(int i=0;i<=N;i++)
            {
                vis[i]=head[i];
            }
            while(flow=dfs(S,INF,T))
                ans+=(ll)flow;
        }
        return ans;
    }
}
using namespace DINIC;
int main()
{
    int n,m,k;
    init();
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n;i++)
    {
        int num;
        scanf("%d",&num);
        for(int j=1;j<=num;j++)
        {
            int x;
            scanf("%d",&x);
            addedge(i,n+x,1);
        }
    }
    for(int i=1;i<=n;i++)
    {
        addedge(0,i,1);
        addedge(n+m+1,i,1);
    }
    for(int i=1;i<=m;i++)
    {
        addedge(n+i,n+m+2,1);
    }
    addedge(0,n+m+1,k);
    ll ans=dinic(0,n+m+2,n+m+3);
    printf("%lld\n",ans);
}

J.Prime Game

暴力

代码:

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int MAXN=1e6+5;
typedef long long ll;
int n;
vector<int> pos[MAXN];
int mi[MAXN];
bool vis[MAXN];
void init()
{
    for(int i=2;i<MAXN;i++)
    {
        if(vis[i]) continue;
        mi[i]=i;
        for(int j=i+i;j<MAXN;j+=i)
        {
            if(mi[j]==0) mi[j]=i;
            vis[j]=true;
        }
    }
}
int a[MAXN];
int main()
{
    init();
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=n;i++)
    {
        int now=a[i];
        while(now!=1)
        {
            if(pos[mi[now]].size()==0) pos[mi[now]].pb(0);
            pos[mi[now]].pb(i);
            int div=mi[now];
            while(now%div==0) now/=div;
        }
    }
    ll ans=0;
    for(int i=2;i<MAXN;i++)
    {
        for(int j=1;j<pos[i].size();j++)
        {
            int now=pos[i][j],la=pos[i][j-1];
            int l=now-la;
            int r=n-now+1;
            ans+=1LL*l*r;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

K.Kangaroo Puzzle

直接随机就能过

代码:

#include<bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
string s="LRUD";
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	srand(time(0));
	string ans="";
	for(int i=1;i<=50000;i++)
	{
		int id=rand()%4;
		ans+=s[id];
	}
	cout<<ans<<endl;
	return 0;
}

M.Mediocre String Problem

思路有点忘了...

好像是马拉车算回文半径之后乘另外一个串倒置后和当前点为后缀的公共前缀的长度

代码:

#include<bits/stdc++.h>
#define pb push_back
typedef long long ll;
const int MAXN=1e6+5;
void pre_KMP(char x[],int m,int next[])
{
    next[0]=m;
    int j=0;
    while(j+1<m&&x[j]==x[j+1]) j++;
    next[1]=j;
    int k=1;
    for(int i=2;i<m;i++)
    {
        int p=next[k]+k-1;
        int L=next[i-k];
        if(i+L<p+1) next[i]=L;
        else
        {
            j=std::max(0,p-i+1);
            while(i+j<m&&x[i+j]==x[j]) j++;
            next[i]=j;
            k=i;
        }
    }
}
void EKMP(char x[],int m,char y[],int n,int next[],int extend[])
{
    pre_KMP(x,m,next);
    int j=0;
    while(j<n&&j<m&&x[j]==y[j]) j++;
    extend[0]=j;
    int k=0;
    for(int i=1;i<n;i++)
    {
        int p=extend[k]+k-1;
        int L=next[i-k];
        if(i+L<p+1) extend[i]=L;
        else
        {
            j=std::max(0,p-i+1);
            while(i+j<n&&j<m&&y[i+j]==x[j]) j++;
            extend[i]=j;
            k=i;
        }
    }
}
char Ma[MAXN*2];
int Mp[MAXN*2],pos[MAXN*2];
int dp[MAXN*2],cnt[MAXN];
void Manacher(char s[],int len)
{
    memset(pos,-1,sizeof(pos));
    int l=0;
    Ma[l++]='$';
    Ma[l++]='#';
    for(int i=0;i<len;i++)
    {
        pos[l]=i;
        Ma[l++]=s[i];
        Ma[l++]='#';
    }
    Ma[l]=0;
    int mx=0,id=0;
    for(int i=0;i<l;i++)
    {
        Mp[i]=mx>i?std::min(Mp[2*id-i],mx-i):1;
        while(i-Mp[i]>=0&&Ma[i+Mp[i]]==Ma[i-Mp[i]]) Mp[i]++;
        if(i+Mp[i]>mx)
        {
            mx=i+Mp[i];
            id=i;
        }
    }
    for(int i=0;i<l;i++)
    {
        dp[i+Mp[i]-1]++;
        if(i>0) dp[i-1]--;
    }
    for(int i=l-1;i>=0;i--)
    {
        dp[i]+=dp[i+1];
    }
    for(int i=0;i<l;i++)
    {
        if(pos[i]==-1) continue;
        cnt[pos[i]]=dp[i];
        //printf("%d %d\n",i,dp[i]);
    }
}
char a[MAXN],b[MAXN];
int nxt[MAXN],pre[MAXN];
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%s",a);
    scanf("%s",b);
    int lena=strlen(a);
    int lenb=strlen(b);
    std::reverse(a,a+lena);
    Manacher(a,lena);
    EKMP(b,lenb,a,lena,nxt,pre);
    //for(int i=0;i<lena;i++)\
        printf("%d %d\n",i,cnt[i]);
    ll ans=0;
    for(int i=1;i<lena;i++)
    {
        ans+=1LL*pre[i]*cnt[i-1];
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sinat_32872703/article/details/85220659