2018 ACM/ICPC 南京站 & GYM 101981
阿新 • • 發佈:2019-01-02
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
現場賽的時候人品爆炸做出來的題,組合數 .
程式碼實現:
/* 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;
}