zoukankan      html  css  js  c++  java
  • 2018 ICPC Asia Nanjing Regional Contest

    solve: 5/13

    Practice link:https://vjudge.net/contest/388613#overview

    A - Adrien and Austin

    题意:给你 n 个石头,编号从1~n,有两个人,每个人每次操作只能从石头中取 1~k 个连续编号的石头,最后不能取的一方为输,问谁会赢。

    思路:先手必输状态:1、k==1且 n%2==0

                                        2、n==0

    代码:

     1 int main()
     2 {
     3      int n,k;
     4      scanf("%d %d",&n,&k);
     5      if(n==0||(k==1&&n%2==0)){
     6        cout<<"Austin"<<endl;
     7      }else{
     8        cout<<"Adrien"<<endl;
     9      }
    10      return 0;
    11 } 
    View Code

    D - Country Meow

    题意:给你 n 个三维方向上的点,让你建立一个中心指挥部,使这个点到这些点的最大距离最短。

    思路:模拟退火求最小球覆盖

    代码:

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define MOD 998244353 
     4 #define INF 0x3f3f3f3f
     5 #define mem(a,x) memset(a,x,sizeof(a))  
     6 #define _for(i,a,b) for(int i=a; i< b; i++)
     7 #define _rep(i,a,b) for(int i=a; i<=b; i++)
     8 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
     9 using namespace std;const double eps=1e-7;
    10 struct point3D
    11 {
    12     double x,y,z;
    13 } data[35];
    14 ll n;
    15 double dis(point3D a,point3D b)
    16 {
    17     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));
    18 }
    19 double solve()
    20 {
    21     double step=100000,ans=1e30,mt;
    22     point3D z;
    23     z.x=z.y=z.z=0;
    24     ll s=0;
    25     while(step>eps)
    26     {
    27         for(int i=0; i<n; i++)
    28             if(dis(z,data[s])<dis(z,data[i])) s=i;
    29         mt=dis(z,data[s]);
    30         ans=min(ans,mt);
    31         z.x+=(data[s].x-z.x)/mt*step;
    32         z.y+=(data[s].y-z.y)/mt*step;
    33         z.z+=(data[s].z-z.z)/mt*step;
    34         step*=0.98;
    35     }
    36     return ans;
    37 }
    38 int main()
    39 { // freopen("t.txt","r",stdin);
    40     double ans;
    41     scanf("%d",&n);
    42         for(int i=0; i<n; i++)
    43             scanf("%lf%lf%lf",&data[i].x,&data[i].y,&data[i].z);
    44         ans=solve();
    45         printf("%.15f
    ",ans);
    46     return 0;
    47 }
    View Code

    G - Pyramid

    题意:如下图所示,给你一个边长为 n 的等边三角形,问你在这个三角形中有多少个等边三角形。

               

    思路:打表找规律,可以推得 num = n*(n+1)*(n+2)*(n+3)/24,因为要取余操作且式子中有除法,因此要求24的逆元,再取余即可。

    代码:

     1 void extend_gcd(ll a,ll b,ll &x,ll &y)
     2 {
     3     if(b==0) {
     4         x=1,y=0;
     5         return;
     6     }
     7     extend_gcd(b,a%b,x,y);
     8     ll tmp=x;
     9     x=y;
    10     y=tmp-(a/b)*y;
    11 }
    12 ll mod_inverse(ll a,ll m)
    13 {
    14     ll x,y;
    15     extend_gcd(a,m,x,y);
    16     return (m+x%m)%m;
    17 }
    18 int main()
    19 {    
    20    ll T,n;
    21     scanf("%lld",&T);
    22     while(T--){
    23         scanf("%lld",&n);
    24         ll sum=1;
    25         for(int i=0;i<=3;i++)
    26         {
    27             sum=sum*(n+i)%Mod;
    28         }
    29         ll k=mod_inverse(24,Mod);
    30         sum=((sum%Mod)*(k%Mod))%Mod;
    31         printf("%lld
    ",sum);
    32     }
    33 }
    View Code

    I - Magic Potion

    题意:有 n 个英雄和 m 个怪兽,每个英雄有可以打到的怪兽的集合且每个英雄只能打一个怪兽。又有 k 瓶药,每个英雄至多用一瓶,一瓶药可以使一个英雄多打一个怪兽。问你最多有几个怪兽被打。

    思路:这题可以看出是一道二分图最大匹配题,首先把一个英雄拆成两个点,每个点都与可以打的怪兽建边,求这个图的最大匹配 ans,然后不考虑有药的情况求二分图的最大匹配 ans2,接下来看条件,如果

     ans2+k<=ans,则输出 ans2+k,否则输出 ans 即可。

    代码:

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define MOD 998244353 
     4 #define INF 0x3f3f3f3f
     5 #define mem(a,x) memset(a,x,sizeof(a))  
     6 #define _for(i,a,b) for(int i=a; i< b; i++)
     7 #define _rep(i,a,b) for(int i=a; i<=b; i++)
     8 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
     9 using namespace std;
    10 const int maxn = 1000005;
    11 const int NUM = 1e4+5;
    12 int n,m,k,flag,ans;
    13 int link[NUM];
    14 bool vis[NUM];
    15 vector<int>g[4*NUM];
    16 bool dfs(int x)
    17 {
    18     for(int i=0;i<g[x].size();i++){
    19         int v=g[x][i];
    20         if(!vis[v]){
    21             vis[v]=1;
    22             if(!link[v]||dfs(link[v])){
    23                 link[v]=x;
    24                 return true;
    25             }
    26         }
    27     }
    28     return false;
    29 }
    30 int main()
    31 {
    32     scanf("%d %d %d",&n,&m,&k);
    33     ans=0;
    34     mem(link,0);
    35     for(int i=1;i<=n;i++){
    36         int t;
    37         scanf("%d",&t);
    38         for(int j=1;j<=t;j++){
    39             int x;
    40             scanf("%d",&x);
    41             g[i].push_back(2*n+x);
    42             g[n+i].push_back(2*n+x);
    43         }
    44     }
    45     for(int i=1;i<=2*n;i++){
    46         mem(vis,0);
    47         if(dfs(i))ans++;
    48     }
    49     int ans2=0;
    50     mem(link,0);
    51     for(int i=1;i<=n;i++){
    52         mem(vis,0);
    53         if(dfs(i))ans2++;
    54     }
    55         if(ans2+k<=ans){
    56             cout<<ans2+k<<endl;
    57         }else{
    58             cout<<ans<<endl;
    59         }
    60     return 0;
    61 }
    View Code

    J - Prime Game

    题意:给你 n 个数,定义    , 为 的不同的质因数的个数。求 。

    思路:应该考虑每个素数因子对答案的贡献,首先对于 第p个元素含有某个素数因子,则该元素对答案的贡献为 ( n - p + 1 )*p。接下来考虑有重复的情况出现,比如说 第 k 个元素(在p之前)也有某个素数因子,则该元素对答案的贡献为 ( n - k + 1 )*k,则第 p 个元素的贡献就变成了 ( n - p + 1 )*( p - k)。然后我们用 pos[ i ][ k ]储存素数因子 i 第 k 次出现的位置,那么我们只需要遍历每个素数因子 i 让sum=sum+ (n - pos[ i ][ k ] + 1)*( pos[ i ][ k ] - pos[ i ][ k - 1])即可,注意让 pos[ i ][ 0 ] = 0。

    代码:

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define MOD 998244353 
     4 #define INF 0x3f3f3f3f
     5 #define mem(a,x) memset(a,x,sizeof(a))  
     6 #define _for(i,a,b) for(int i=a; i< b; i++)
     7 #define _rep(i,a,b) for(int i=a; i<=b; i++)
     8 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
     9 using namespace std;
    10 const int maxn = 1000005;
    11 const int NUM = 1e4+5;
    12 
    13 int n,a[maxn];
    14 vector<int>pos[maxn];
    15 void dec(int p)
    16 {
    17     int n=a[p];
    18     for(int i=2;i*i<=n;i++){
    19         if(n%i==0)
    20         {
    21             pos[i].push_back(p);
    22             while(n%i==0)n/=i;   //
    23         }
    24     }
    25     if(n>1)pos[n].push_back(p);
    26 }
    27 int main()
    28 {
    29     scanf("%d",&n);
    30     for(int i=2;i<=1000000;i++)pos[i].push_back(0);
    31     for(int i=1;i<=n;i++){
    32         scanf("%d",&a[i]);
    33         dec(i);
    34     }
    35     ll sum=0;
    36     for(int i=2;i<=1000000;i++){
    37         for(int k=1;k<pos[i].size();k++){
    38             sum+=(ll)(n-pos[i][k]+1)*(pos[i][k]-pos[i][k-1]);
    39         }
    40     }
    41     cout<<sum;
    42     return 0;
    43 }
    View Code

    K - Kangaroo Puzzle

    题意:在一个20×20的地图上,11表示有袋鼠,00表示有障碍物,边界外和障碍物上不能走。
    要求给出一个50000步以内的操作,每一步操作为'L', 'R', 'U', 'D', 表示所有袋鼠一起动的方向,如果某个袋鼠下一个地方是不能走的,那么它那一步会忽略,使得所有袋鼠都聚集在一起。

    思路:因为20x20非常小且有50000步可以操作,因此随机输出50000个  'L', 'R', 'U', 'D', 即可。(神奇)

    代码:

     1 char a[25][25];
     2 int main()
     3 {
     4     int n,m;
     5     scanf("%d %d",&n,&m);
     6     getchar();
     7     for(int i=1;i<=n;i++){
     8         scanf("%s",a);
     9     }
    10     n=50000;
    11     char s[5]="URLD";
    12     while(n--){
    13         printf("%c",s[rand()%4]);
    14     }
    15     return 0;
    16 }
    View Code

     

    越自律,越自由
  • 相关阅读:
    .net 日期格式化
    grunt 上手
    设计模式的认识
    顺时针打印矩阵
    WCF 框架运行时类图
    Python闭包详解
    软件用了那些技术
    zoj 1610 Count the Colors(线段树延迟更新)
    快速提高自己的技术的办法?有两个方法
    纯win32实现PNG图片透明窗体
  • 原文地址:https://www.cnblogs.com/ha-chuochuo/p/13473039.html
Copyright © 2011-2022 走看看