1. 程式人生 > >2018 ACM/ICPC 南京站 & GYM 101981

2018 ACM/ICPC 南京站 & GYM 101981

A  Adrien and Austin

給定一堆石子,每個人可以從其中連續的拿出一段,最優情況下,問最後誰能獲得遊戲的勝利。

需要注意的是,當n==0時,此時先手是無法取石子的,此時輸出Austin

程式碼實現:

/*
Look at the star
Look at the shine for U
*/
#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
#define sl(x) scanf("%lld",&x)
using namespace std;
const int N = 1e6+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}

int main()
{
    ll n,k,i,j;
    while(~sl(n))
    {
        sl(k);
        if(n == 0)
            puts("Austin");
        else if(k >= 2)
            puts("Adrien");
        else
        {
            if(n&1)
                puts("Adrien");
            else
                puts("Austin");
        }
    }
}

D Country Meow

最小球覆蓋的模板題,上交的模板中,程式碼照抄就ok,試了好幾個模擬退火,都wa掉了,三分也可以。

程式碼實現:

/*
Look at the star
Look at the shine for U
*/
#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
#define sl(x) scanf("%lld",&x)
using namespace std;
const int N = 1e6+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-12;
const double PI = acos(-1);
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}
struct Tpoint{
	double x,y,z;
};
int npoint,nouter;
Tpoint pt[200000],outer[4],res;
double radius;
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;
	int i,j;
	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(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(i = 0;i < 2;i++)
			{
				for(j = 0;j < 2;j++)
				{
					m[i][j] = dot(q[i],q[j])*2;
				}
			}
			for(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(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(i = 0;i < 3;i++)
			{
				for(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(j = 0;j < 3;j++)
			{
				for(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(i = 0;i < 3;i++)
					m[i][j] = dot(q[i],q[j])*2;
			}
			res = outer[0];
			for(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]);
	}
//	cout << nouter <<"***" << radius<<"**"<<endl;
}
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()
{
	int i,j,k;
	scanf("%d",&npoint);
	for(i = 0;i < npoint;i++)
	{
		scanf("%lf%lf%lf",&pt[i].x,&pt[i].y,&pt[i].z);
	}
	double ans = smallest_ball();
	printf("%.15f\n",ans);
	return 0;
}

G Pyramid

現場賽的時候人品爆炸做出來的題,組合數 {C_{n+3}}^{4} .

程式碼實現:

/*
Look at the star
Look at the shine for U
*/
#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
#define sl(x) scanf("%lld",&x)
using namespace std;
const int N = 1e6+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}

int main()
{
    ll t,i,j,k,n;
    ll inv24 = inv(24);
    for(sl(t);t--;)
    {
        sl(n);
        n += 3;
        ll ans = n*(n-1)%mod*(n-2)%mod*(n-3)%mod*inv24%mod;
        printf("%lld\n",ans);
    }
    return 0;
}

I Magic Potion

網路流的模板題

程式碼實現:

/*
Look at the star
Look at the shine for U
*/
#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
#define sl(x) scanf("%lld",&x)
using namespace std;
const int N = 1e6+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}
struct point{
    int to,next,w;
}p[N];
int num[N],head[N],cnt = 0;
void init()
{
    memset(head,-1,sizeof(head));
    memset(num,0,sizeof(num));
    cnt = 0;
}
void add(int u,int v,int w)
{
    p[cnt].next=head[u];
    p[cnt].to=v;
    p[cnt].w=w;
    head[u] = cnt++;
}
int bfs(int st,int en)
{
    queue<int>Q;
    memset(num,0,sizeof(num));
    num[st]=1;
    Q.push(st);
    while (!Q.empty())
    {
        int t = Q.front();
        Q.pop();
        if (t == en)
            return 1;
        for (int i = head[t];~i;i = p[i].next)
        {
            int to=p[i].to;
            int w=p[i].w;
            if (w&&num[to]==0)
            {
                num[to]=num[t]+1;
                if (to==en)
                    return 1;
                Q.push(to);
            }
        }
    }
    return 0;
}
int dfs(int u,int flow,int st,int en)
{
    if (u==en)
        return flow;
    int res=0;
    for (int i=head[u];i!=-1;i=p[i].next)
    {
        int to=p[i].to;
        int w=p[i].w;
        if (w&&num[to]==num[u]+1)
        {
            int temp=dfs(to,min(flow-res,w),st,en);
            p[i].w-=temp;
            p[i^1].w+=temp;
            res+=temp;
            if (res==flow)
                return res;
        }
    }
    if (!res)
        num[u]=-1;
    return res;
}
int Dinic(int st,int en)
{
    int res=0;
    while (bfs(st,en))
        res+=dfs(st,INF,st,en);
    return res;
}
int main()
{
    int n,m,k,v,x,i,j;
    scanf("%d%d%d",&n,&m,&k);
    init();
    int s = n+m+1,e = n+m+3,temp_po = n+m+2;
    for (i=1;i<=n;i++)
    {
        scanf("%d",&x);
        for (j=0;j<x;j++)
        {
            scanf("%d",&v);
            add(i,n+v,1);
            add(n+v,i,0);
        }
    }
    for (i = 1;i <= m;i++)
        add(i+n,e,1),add(e,i+n,0);
    for (i = 1;i <= n;i++)
    {
        add(s,i,1);
        add(i,s,0);
        add(temp_po,i,1);
        add(i,temp_po,0);
    }
    add(s,temp_po,k);
    add(temp_po,s,0);
    int ans = Dinic(s,e);
    printf("%d\n",ans);
    return 0;
}

J Prime Game

考慮每一個質數對於總答案的貢獻。

程式碼實現:

/*
Look at the star
Look at the shine for U
*/
#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
#define sl(x) scanf("%lld",&x)
using namespace std;
const int N = 1e6+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}
ll s[N],prim[N],cnt,n,f[N];
vector <ll> vec[N];
vector <ll> v[N];

void init()
{
    for(ll i = 2;i < 1000005;i++)
    {
        if(!f[i])
        {
            prim[cnt++]=i;
            vec[i].push_back(i);
        }
        for(int j=0;j<cnt;j++)
        {
            if(i*prim[j] >= 1000001)
                break;
            f[i*prim[j]]=1;
            vec[i*prim[j]]=vec[i];
            if(i%prim[j]==0)
                break;
            else
                vec[i*prim[j]].push_back(prim[j]);
        }
    }
}

int main()
{
    ll i,j,k;
    init();
    sl(n);
    for(i = 1;i <= n;i++)
    {
        sl(s[i]);
        if(vec[s[i]].size())
        for(j = vec[s[i]].size()-1;j >= 0;j--)
                v[vec[s[i]][j]].push_back(i);
    }

    ll ans = 0;
    for(i = 0;i < cnt;i++)
    {
        if(v[prim[i]].size()==0) continue;
        ll now=0,tmp=0;
        for(j = 0;j < v[prim[i]].size();j++)
        {
            tmp += (v[prim[i]][j]-now)*(v[prim[i]][j]-now-1)/2;
            now=v[prim[i]][j];
        }
        tmp += (n+1-now)*(n-now)/2;
        ans += n*(n+1)/2-tmp;
    }
    printf("%lld\n",ans);
    return 0;
}

K Kangaroo Puzzle

由於此題的資料量很小,而且 最後的答案是特判,所以可以直接輸出10w個隨機的方向。看人品過題。

程式碼實現:

/*
Look at the star
Look at the shine for U
*/
#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
#define sl(x) scanf("%lld",&x)
using namespace std;
const int N = 1e6+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}
ll s[105][105];

int main()
{
     ll n,m,i,j,k;
     sl(n);sl(m);
     for(i = 0;i < n;i++)
        scanf("%s",s[i]);
    srand(time(0));
    char ans[4] = {'L','R','D','U'};
    int l = 0,r = 0;
    for(i = 0;i <= 10002;i++)
    {
        char ch = ans[rand()%4];
        printf("%c",ch);
    }
    puts("");
    return 0;
}