以下所有AC题解程序来自“仙客传奇”团队。 AC题数:6/13 ADGIJK
A. Adrien and Austin
AC的C++语言程序:
#include
using namespace std;
int main(void) {
int n, k;
scanf("%d%d", &n, &k);
if (n == 0)
printf("Austin");
else if (k == 1)
printf("%s", n & 1 ? "Adrien" : "Austin");
else
printf("Adrien");
return 0;
}
AC的C++语言程序:
#include
using namespace std;
int main()
{
int n,k;
while(cin>>n>>k){
if(n==0) {
printf("Austin\n");
continue;
}
if(n<=k) {
printf("Adrien\n");
continue;
}
if(k==1) {
if(n&1) printf("Adrien\n");
else printf("Austin\n");
}
else {
printf("Adrien\n");
}
}
}
B. Tournament
题解链接:
Gym - 101981B - Tournament 2018icpc南京站现场赛B题
2018 ACM-ICPC 南京站 B Tournament dp+决策单调性+wqs二分
C. Cherry and Chocolate
D. Country Meow
AC的C++语言程序:
#include
using namespace std;
const double eps=1e-3;
struct Tpoint{
double x,y,z;
};
int npoint,nouter;
Tpoint pt[200000],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;
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(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()
{
while(scanf("%d",&npoint)!=EOF){
for(int i=0;i<npoint;i++){
scanf("%lf%lf%lf",&pt[i].x,&pt[i].y,&pt[i].z);
}
printf("%.15f\n",smallest_ball());
}
return 0;
}
E. Eva and Euro coins
题解链接:
ACM-ICPC 2018 南京赛区现场赛 E. Eva and Euro coins (思维)
F. Frank
G. Pyramid
AC的C++语言程序:
#include
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const ll inv = 41666667;
int main()
{
int t;
ll n;
scanf("%d",&t);
while(t-- && scanf("%lld" ,&n) != EOF){
printf("%lld\n",n * (n+1) % mod * (n+2) % mod * (n+3) % mod * inv % mod);
}
return 0;
}
AC的C++语言程序:
#include
using namespace std;
typedef long long LL;
const LL MOD = 1e9 + 7;
LL fpm(LL base, LL p) {
LL ret = 1;
do {
if (p & 1) ret = base * ret % MOD;
base = base * base % MOD;
} while (p >>= 1);
return ret;
}
int main(void) {
int t;
LL n;
scanf("%d", &t);
LL rev24 = fpm(24, MOD - 2);
while (t--) {
scanf("%lld", &n);
printf("%lld\n", n * (n + 1) % MOD * (n + 2) % MOD
* (n + 3) % MOD * rev24 % MOD);
}
return 0;
}
AC的C++语言程序:
#include
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll quick_pow(ll a,ll b,ll mod){
ll ans=1;
while(b)
{
if(b&1) ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
ll inv(ll x,ll mod){
return quick_pow(x,mod-2,mod);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
ll n,ans;
scanf("%lld",&n);
ans=(((n*(n+1)%mod)*(n+2)%mod)*(n+3)%mod)%mod;
ans=ans*inv(24,mod)%mod;
printf("%lld\n",ans);
}
return 0;
}
H. Huge Discount
题解链接:
gym 101981H 2018ICPC南京区域赛 H Huge Discount
I. Magic Potion
AC的C++语言程序:
#include
#include
#include
#include
using namespace std;
const int inf = 0x7f7f7f7f;
int MM[1500][1500],M[1500][1500],pre[1500],flow[1500],aaaa[510];
int BFS(int s,int t)
{
queue<int> q;
q.push(s);
memset(pre,-1,sizeof(pre));
flow[s] = inf;
while(!q.empty())
{
int u = q.front();
q.pop();
for(int v = 0;v <= t;++v)
if(M[u][v] && pre[v] == -1)
{
pre[v] = u;
flow[v] = min(flow[u],M[u][v]);
q.push(v);
}
}
if(pre[t] == -1)
return -1;
else
return flow[t];
}
int Maxflow(int s,int t)
{
int increase,res = 0;
while((increase = BFS(s,t)) != -1)
{
int k = t,last = pre[k];
while(k != s)
{
M[last][k] -= increase;
M[k][last] += increase;
k = pre[k];last = pre[k];
}
res += increase;
}
return res;
}
int main()
{
int n,m,k,x,temp,t,ans;
cin>>n>>m>>k;
t = n + m + 2;
M[0][1] = k;
for(int i = 1;i <= n;++i) M[0][i + 1] = 1,M[1][i + 1] = 1;
for(int i = 1;i <= m;++i) M[n + i + 1][t] = 1;
for(int i = 1;i <= n;++i)
{
cin>>x;
for(int j = 0;j < x;++j)
{
cin>>temp;
M[i + 1][temp + n + 1] = 1;
}
}
ans = Maxflow(0,t);
cout<<ans<<endl;
return 0;
}
AC的C++语言程序:
#include
using namespace std;
const int INF=0x3f3f3f3f;
const int MAX_V=1000+5;
struct edge{
int to,cap,rev;
edge(int _to,int _cap,int _rev):to(_to),cap(_cap),rev(_rev){}
};
vector<edge>G[MAX_V];
int level[MAX_V];
int iter[MAX_V];
int n,m,k;
void add_edge(int from,int to,int cap)
{
G[from].push_back(edge(to,cap,G[to].size()));
G[to].push_back(edge(from,0,G[from].size()-1));
}
void bfs(int s)
{
memset(level,-1,sizeof(level));
queue<int>que;
level[s]=0;
que.push(s);
while(!que.empty()){
int v=que.front();que.pop();
for(int i=0;i<G[v].size();i++){
edge &e=G[v][i];
if(e.cap>0&&level[e.to]<0){
level[e.to]=level[v]+1;
que.push(e.to);
}
}
}
}
int dfs(int v,int t,int f)
{
if(v==t){
return f;
}
for(int &i=iter[v];i<G[v].size();i++){
edge &e=G[v][i];
if(e.cap>0&&level[v]<level[e.to]){
int d=dfs(e.to,t,min(f,e.cap));
if(d>0){
e.cap-=d;
G[e.to][e.rev].cap+=d;
return d;
}
}
}
return 0;
}
int max_flow(int s,int t)
{
int flow=0;
for(;;){
bfs(s);
if(level[t]<0){
return flow;
}
memset(iter,0,sizeof(iter));
int f;
while((f=dfs(s,t,INF))>0){
flow+=f;
}
}
}
int main()
{
int s,t;
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<n;i++){
int h,v;
scanf("%d",&h);
while(h--){
scanf("%d",&v);
add_edge(i+1,v+n,1);
}
}
for(int i=1;i<=n;i++){
add_edge(0,i,1);
}
for(int i=n+1;i<=n+m;i++){
add_edge(i,n+m+2,1);
}
add_edge(0,n+m+1,k);
for(int i=1;i<=n;i++){
add_edge(n+m+1,i,1);
}
printf("%d\n",max_flow(0,n+m+2));
return 0;
}
J. Prime Game
AC的C++语言程序:
#include
#include
#include
#include
using namespace std;
const int N = 1000005;
int n,a[N];
vector<int> pos[N];
void dec(int p){
int n = a[p];
for(int i=2; i*i <= n; i++){
if(n%i == 0){//因子
pos[i].push_back(p);
while(n%i == 0)
n /= i;
}
}
if(n > 1)
pos[n].push_back(p);
}
int main()
{
for(int i=2; i<N; i++)
pos[i].push_back(0);
scanf("%d",&n);
for(int i=1; i <= n; i++){
scanf("%d",&a[i]);
dec(i);
}
long long ans = 0;
for(int i=2; i < N; i++){
for(int k=1; k < pos[i].size(); k++)
ans += (long long)(n-pos[i][k]+1) * (pos[i][k]-pos[i][k-1]);
}
cout << ans << endl;
}
//注意:本题是单输入单输出。
//每次只能操作一组数据
/*
* 第 p个位置上的数,其包含的任意一个素因子
* 它原本应当产生的贡献有 (n−p+1)*p(n−p+1)*p
* 但是若其前面出现过一样的素数
* 那么应当减去一些重复计算的区间。
* 假设它前面的和它一样的素数,最后一次出现在 q 位置
* 那么就应当减去 (n−p+1) * q(n−p+1) * q
* 即 a[p] 包含的任意一个质因子其产生的贡献为 (n−p+1)*p−(n−p+1)*q = (n−p+1)*(p−q)
* 不妨用 pos[i][k]来存储每个素因子的 “p”
* pos[i][k−1]存储每个素因子的 “q”。
* 换句话说,pos[i][k]代表某个素因子 i在 a[1∼n] 中第 k 次“出现”的位置是 pos[i][k]
* 特别地,令 pos[i][0]=0。
* 那么对于任意素因子 i,它对答案的贡献是 (n−pos[i][k]+1)*(pos[i][k]−pos[i][k−1])
* 我们可以对 a[1∼n]分解质因数,然后更新相应的 pos[i][k]
*
*/
AC的C++语言程序:
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn = 1e6;
vector<int> vv[maxn + 10];
void euler(int n,int i)
{
int a = n;
for(int j = 2;j * j <= a; ++j)
if(a % j == 0)
{
vv[j].push_back(i);
while(a % j == 0)
a /= j;
}
if(a > 1) vv[a].push_back(i);
}
int main()
{
int n,a;
for(int i = 2;i < maxn;++i) vv[i].push_back(0);
cin>>n;
for(int i = 1;i <= n;++i)
{
cin>>a;
euler(a,i);
}
ll ans = 0;
for(int i = 2;i < maxn;++i)
{
for(int k = 1;k < vv[i].size();++k)
ans += (ll)(n - vv[i][k] + 1) * (vv[i][k] - vv[i][k - 1]);
}
cout<<ans<<endl;
return 0;
}
AC的C++语言程序:
#include
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
int f[maxn],prime[maxn],cnt,a[maxn],n;
vector<int> pre[maxn];
vector<int> pos[maxn];
void init()
{
for(int i=2;i<maxn;i++)
{
if(!f[i])
{
prime[cnt++]=i;
pre[i].push_back(i);
}
for(int j=0;j<cnt;j++)
{
if(i*prime[j]>=maxn)
break;
f[i*prime[j]]=1;
pre[i*prime[j]]=pre[i];
if(i%prime[j]==0)
break;
else
pre[i*prime[j]].push_back(prime[j]);
}
}
}
int main()
{
init();
ll ans=0;
scanf("%d",&n);
for(int i=1; i<=n; ++i) {
scanf("%d",a+i);
for(int j=pre[a[i]].size()-1; j>=0; --j)
pos[pre[a[i]][j]].push_back(i);
}
ans=0;
for(int i=0; i<cnt; i++) {
if(pos[prime[i]].size()==0)
continue;
ll now=0,tp=0;
for(int j=0; j<pos[prime[i]].size(); j++) {
tp+=(pos[prime[i]][j]-now)*(pos[prime[i]][j]-now-1)/2;
now=(ll)pos[prime[i]][j];
}
tp+=(n+1-now)*(n-now)/2;
ans+=(ll)n*(n+1)/2-tp;
}
printf("%lld\n",ans);
for(int i=0; i<maxn; i++)
pos[i].clear();
}
K. Kangaroo Puzzle
AC的C++语言程序:
#include
#include
#include
#include
using namespace std;
int main()
{
char dir[] = {'U','D','L','R'};
srand(time(NULL));
int n,m,x;
x = 50000;
while(x--)
putchar( dir[rand() % 4]);
return 0;
}
L. Lagrange the Chef
M. Mediocre String Problem
题解链接:
Gym - 101981M The 2018 ICPC Asia Nanjing Regional Contest M.Mediocre String Problem Manacher+扩增KMP
参考链接:
ADEGIJKM 2018 ACM-ICPC南京区域赛题解
ADEGIJKM 2018 ACM-ICPC南京区域赛题解