记录下第一次一个人vp整场比赛,而且还打到金牌区啦~
虽然是省赛 
比赛地址:Dashboard - The 2024 International Collegiate Programming Contest in Hubei Province, China - Codeforces 
A 
题意:给出 $x,y$ ,求 $a,b$ 满足:
 
令 $a=1$ 即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <bits/stdc++.h>  using  namespace  std;#define  LL long long int  main ()     int  t;     cin>>t;     while (t--)     {         LL a,b;         cin>>a>>b;         LL ans=a*b/__gcd(a,b)/__gcd(a,b);         cout<<1 <<" " <<ans<<endl;     }     return  0 ; } 
B 
题意:在二维平面上给出 $n$ 个点,在其中选取若干个点构成凸多边形且使多边形面积最小。$n\leq 100$
 
很明显构成三角形面积最小。直接暴力枚举三个顶点,求面积时用叉积即可。注意判断三角形是否存在。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 #include <bits/stdc++.h>  using  namespace  std;pair<int ,int >v[200 ]; double  cross (int  i,int  j,int  k)     pair<int ,int >ij,ik;     ij={v[i].first-v[j].first,v[i].second-v[j].second};     ik={v[i].first-v[k].first,v[i].second-v[k].second};     return  (double )1 *abs (ij.first*ik.second-ij.second*ik.first)/2 ; } void  solve ()     int  n;     cin>>n;     for (int  i=1 ;i<=n;i++)cin>>v[i].first>>v[i].second;     double  ans=9999999999 ;     for (int  i=1 ;i<=n;i++)     {         for (int  j=1 ;j<=n;j++)         {             for (int  k=1 ;k<=n;k++)             {                 if (i==j || j==k || i==k)continue ;                                  double  tmp=cross (i,j,k);                 if (tmp>0.1 )                 ans=min (cross (i,j,k),ans);             }         }     }     if (ans==9999999999  || ans<0.5 )cout<<-1 <<endl;     else  cout<<ans<<endl; } int  main ()     int  t;     cin>>t;     while (t--)solve ();     return  0 ; } 
E 
水题
G 
题意:在一个 $19\times 19$ 的棋盘上下围棋,给出每一步之后黑棋和白起分别被提多少颗。
 
一个大模拟题,时限4s,可以暴力过。
每一步都全局dfs一次,先找对方每一个块的气,若气为零就把这个块清除掉,然后再找下棋方每一个块的气。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 #include <bits/stdc++.h>  using  namespace  std;int  bd[20 ][20 ];int  t;bool  v[20 ][20 ];int  dx[4 ]={0 ,0 ,1 ,-1 };int  dy[4 ]={1 ,-1 ,0 ,0 };int  sum;int  ans;vector<pair<int ,int > >qz; void  dfs (int  x,int  y)     qz.push_back ({x,y});     v[x][y]=1 ;     for (int  i=0 ;i<=3 ;i++)     {         int  nx=x+dx[i];         int  ny=y+dy[i];         if (nx<1  || nx>19  || ny<1  || ny>19  || v[nx][ny])continue ;         if (bd[nx][ny]==0 )sum++;         else  if (bd[nx][ny]==t)dfs (nx,ny);     } } void  check ()     memset (v,0 ,sizeof (v));     for (int  i=1 ;i<=19 ;i++)     {         for (int  j=1 ;j<=19 ;j++)         {             if (!v[i][j] && bd[i][j]==t)             {                                  qz.clear ();                 sum=0 ;                 dfs (i,j);                                  if (!sum && qz.size ())                 {                     ans+=qz.size ();                     for (auto  i:qz)                     {                         bd[i.first][i.second]=0 ;                     }                 }                              }         }     } } int  main ()     ios_base::sync_with_stdio (false );     cin.tie (0 );     cout.tie (0 );     int  n;     cin>>n;     for (int  i=1 ,op=1 ;i<=n;i++,op^=3 )     {         int  x,y;         cin>>x>>y;         bd[x][y]=op;         t=op^3 ;         ans=0 ;         check ();         int  ans1=ans;         ans=0 ;         t=op;         check ();         int  ans2=ans;         if (op==1 )cout<<ans2<<" " <<ans1<<endl;         else  cout<<ans1<<" " <<ans2<<endl;                                         }     return  0 ; } 
H 
题意:在一个 $1000\times 1000$ 的池塘里有不超过10个池塘有鱼,每个池塘的鱼不超过3条,现在用炸弹炸池塘,每次以炸弹为中心的“十”字范围内5个池塘每个池塘的鱼减少1条。求炸死所有的鱼最少需要多少次。
 
考虑状压dp来存状态。把状态构造成一个不超过10位的四进制数,存下所有能炸到鱼的位置,这样的位置不超过50个,然后用bfs的方法暴力炸鱼,最终状态为 $dp[0]$ 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 #include <bits/stdc++.h>  using  namespace  std;#define  LL long long LL pow4[20 ]; int  dp[2000005 ];int  v[2000005 ];int  n,m,k;bool  check (LL st,int  p)     st/=pow4[p];     st%=4 ;     if (st)return  1 ;     else  return  0 ; } void  de (long  long  status)     int  dd[20 ]={0 };     int  tot=0 ;     while (status)     {         dd[++tot]=status%4 ;         status/=4 ;     }     for (int  i=k;i>=1 ;i--)cout<<dd[i];cout<<endl; } int  main ()     ios_base::sync_with_stdio (false );     cin.tie (0 );     cout.tie (0 );     pow4[0 ]=1 ;     for (int  i=1 ;i<=12 ;i++)pow4[i]=pow4[i-1 ]*4 ;          cin>>n>>m>>k;     LL status=0 ;     map<pair<int ,int >,int >mp;     vector<pair<int ,int > >pos;     for (int  i=1 ;i<=k;i++)     {         int  x,y,cnt;         cin>>x>>y>>cnt;         mp[{x,y}]=i;         pos.push_back ({x,y});         if (x>1 )pos.push_back ({x-1 ,y});         if (x<n)pos.push_back ({x+1 ,y});         if (y>1 )pos.push_back ({x,y-1 });         if (y<m)pos.push_back ({x,y+1 });         status+=pow4[i-1 ]*cnt;     }     int  ans=0 ;     queue<LL>q;     bool  flag=0 ;     dp[status]=0 ;     q.push (status);     while (q.size ())     {         LL sta=q.front ();         q.pop ();         int  bit[20 ]={0 };         int  tot=0 ;         LL tst=sta;         while (tst)         {             bit[tot++]=tst%4 ;             tst/=4 ;         }                  for (auto  i:pos)         {             int  x=i.first;             int  y=i.second;             LL st=sta;                          if (mp[{x,y}]!=0 )             {                 if (bit[mp[{x,y}]-1 ])st-=pow4[mp[{x,y}]-1 ];             }             if (mp[{x-1 ,y}]!=0 )             {                 if (bit[mp[{x-1 ,y}]-1 ])st-=pow4[mp[{x-1 ,y}]-1 ];             }             if (mp[{x+1 ,y}]!=0 )             {                 if (bit[mp[{x+1 ,y}]-1 ])st-=pow4[mp[{x+1 ,y}]-1 ];             }             if (mp[{x,y-1 }]!=0 )             {                 if (bit[mp[{x,y-1 }]-1 ])st-=pow4[mp[{x,y-1 }]-1 ];             }             if (mp[{x,y+1 }]!=0 )             {                 if (bit[mp[{x,y+1 }]-1 ])st-=pow4[mp[{x,y+1 }]-1 ];             }             if (!v[st])             {                 v[st]=1 ;                 dp[st]=dp[sta]+1 ;                 q.push (st);                                                                }                      }     }     cout<<dp[0 ];          return  0 ; } 
J 
题意:给出一个长为 $n$ 的数组 $a$ ,每次任选两个数将其删除并将这两个数的平均数加入数组。求最后的数的期望。
 
可以猜测最后的数就是平均数,因为每个数被选的概率相同。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <bits/stdc++.h>  using  namespace  std;const  int  mod=998244353 ;long  long  qsm (long  long  base, long  long  power)      long  long  result = 1 ;     while  (power > 0 )      {         if  (power & 1 ) result = result * base % mod;         power >>= 1 ;         base = (base * base) % mod;     }     return  result; } int  main ()     int  n;     cin>>n;     long  long  sum=0 ;     for (int  i=1 ;i<=n;i++)     {         int  x;         cin>>x;         sum=(sum+x)%mod;     }     long  long  d=qsm (n,mod-2 );     sum=(sum*d)%mod;     cout<<sum;     return  0 ; } 
L 
题意:有一个包含无数多个整数点的完全图,任两个点的距离 $d(i,j)=lcm(i,j)$ 。先给出两个点 $a,b$ ,求这两个点的最短路。
 
分类讨论,假设 $a<b $:
若 $a=b $ ,答案是0; 
若 $b%a=0$ ,答案是 $b$ ; 
若 $gcd(a,b)!=1$ ,答案是 $a+b$ ; 
若 $gcd(a,b)=1$ ,那么从 $a$ 到 $b$ 只可能经过 $a$ 、$b$ 、$2$ 、$a$ 的最小质因数、$b$ 的最小质因数。找出这5个数两两的距离跑floyed即可。若分类讨论很可能漏情况。  
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 #include <bits/stdc++.h>  using  namespace  std;#define  int long long const  int  inf=1e9 ;int  Lcm (int  a,int  b)     return  a*b/__gcd(a,b); } void  solve ()     int  a,b;     cin>>a>>b;     if (a>b)swap (a,b);     if (a==b)     {         cout<<0 <<endl;         return  ;     }     if (b%a==0 )     {         cout<<b<<endl;         return  ;     }     if (__gcd(a,b)!=1 )     {         cout<<a+b<<endl;         return  ;     }     int  yza=0 ,yzb=0 ;     for (int  i=2 ;i<=sqrt (a);i++)     {         if (a%i==0 )         {             yza=i;             break ;         }     }     if (!yza)yza=inf;     for (int  i=2 ;i<=sqrt (b);i++)     {         if (b%i==0 )         {             yzb=i;             break ;         }     }     if (!yzb)yzb=inf;          int  f[10 ][10 ];     memset (f,0x3f ,sizeof (f));     for (int  i=1 ;i<=5 ;i++)f[i][i]=0 ;     int  tmp[6 ]={0 ,a,b,2 ,yza,yzb};     for (int  i=1 ;i<=5 ;i++)     {         for (int  j=1 ;j<=5 ;j++)         {             if (i==j)f[i][j]=0 ;             else  f[i][j]=Lcm (tmp[i],tmp[j]);         }     }     for (int  k=1 ;k<=5 ;k++)     {         for (int  i=1 ;i<=5 ;i++)         {             for (int  j=1 ;j<=5 ;j++)             {                 f[i][j]=min (f[i][j],f[i][k]+f[k][j]);             }         }     }     cout<<f[1 ][2 ]<<endl;      } signed  main ()     int  t;     cin>>t;     while (t--)solve ();     return  0 ; }