题意:对于 1 ∼ n 1\sim n 1 ∼ n P P P ∑ i % P i \sum i\%P_i ∑ i % P i  
 
容易证明,最优排列为 { 2 , 3 , 4 , ⋯   , n , 1 } \{2,3,4,\cdots,n,1\} { 2 , 3 , 4 , ⋯ , n , 1 } 1 + 2 + ⋯ + ( n − 1 ) = n ( n − 1 ) 2 1+2+\cdots+(n-1)=\frac{n(n-1)}{2} 1 + 2 + ⋯ + ( n − 1 ) = 2 n ( n − 1 )  
By risujiroh 
1 2 3 4 5 6 7 8 9 10 11 #include  <bits/stdc++.h>  using  namespace  std;using  lint = long  long ;template <class  T  =int > using  V = vector<T>;template <class  T  =int > using  VV = V< V<T> >;int  main ()    cin.tie (nullptr ); ios::sync_with_stdio (false );   lint n; cin >> n;   cout << n * (n - 1 ) / 2  << '\n' ; } 
题意:有 n n n k k k 
 
思考可得不开心人数等于连续的段数,每次操作可以将中间的一段翻转,此时连续段数 − 2 -2 − 2 max  ( c n t − 2 k , 1 ) \max(cnt-2k,1) max ( c n t − 2 k , 1 ) 
By jah_melon 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <bits/stdc++.h>  #define  ll long long using  namespace  std;template  <typename  T> void  read (T &x)     x=0 ;char  ch=getchar ();int  fh=1 ;     while  (ch<'0' ||ch>'9' ){if  (ch=='-' )fh=-1 ;ch=getchar ();}     while  (ch>='0' &&ch<='9' )x=x*10 +ch-'0' ,ch=getchar ();     x*=fh; } int  m,n,sum=1 ;string s; int  main ()     cin>>n>>m;     cin>>s;     for  (int  i=0 ;i<s.length ()-1 ;i++)if  (s[i]!=s[i+1 ])sum++;     sum=max (1 ,sum-m*2 );     cout<<n-sum<<endl;     return  0 ; } 
题意:有 n n n m m m 
 
显然每次取最贵的商品使用优惠券。用优先队列维护即可。
By heno239 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 void  solve ()      priority_queue<int > q;     int  n, m; cin >> n >> m;     rep (i, n) {         int  a; cin >> a; q.push (a);     }     rep (i, m) {         int  x = q.top (); q.pop ();         q.push (x / 2 );     }     ll sum = 0 ;     while  (!q.empty ()) {         sum += q.top (); q.pop ();     }     cout << sum << endl; } signed  main ()      cin.tie (0 );     ios::sync_with_stdio (false );     solve ();          return  0 ; } 
题意:给你两个数 a , b a,b a , b a , b a,b a , b 
 
a , b a,b a , b gcd  ( a , b ) \gcd(a,b) g cd( a , b ) gcd  ( a , b ) \gcd(a,b) g cd( a , b ) 1 1 1 
By risujiroh 
1 2 3 4 5 6 7 8 9 10 11 12 13 template <class Z> map<Z, int > factorize (Z n)    map<Z, int > res;   for  (Z i = 2 ; i * i <= n; ++i) while  (n % i == 0 ) ++res[i], n /= i;   if  (n != 1 ) ++res[n];   return  res; } int  main ()    cin.tie (nullptr ); ios::sync_with_stdio (false );   lint a, b; cin >> a >> b;   auto  mp = factorize (__gcd(a, b));   cout << mp.size () + 1  << '\n' ; } 
题意:有 n n n i i i a i a_i a i  
 
先从小到大排序,枚举 ( i , j ) (i,j) ( i , j ) i , j i,j i , j k > j k>j k > j a k < a i + a j a_k<a_i+a_j a k  < a i  + a j  
By sumitacchan 
1 2 3 4 5 6 7 8 9 10 11 12 13 signed  main ()     int  N; cin >> N;     vec L (N)  ; cin >> L;     Sort (L);     int  ans = 0 ;     REP (i, N) FOR (j, i + 1 , N){         ans += Lower_bound (L, L[i] + L[j]) - j - 1 ;     }     Out (ans);     return  0 ; } 
题意:一个底为 a × a a\times a a × a b b b x x x x ≤ a 2 b x\le a^2b x ≤ a 2 b 
 
将 x x x a a a 
By jiangly 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include  <bits/stdc++.h>  using  namespace  std;constexpr  double  PI = atan2 (0 , -1 );int  main ()      ios::sync_with_stdio (false );     cin.tie (nullptr );     int  a, b, x;     cin >> a >> b >> x;     double  y = 1.0  * x / a;     double  g;     if  (2  * y <= a * b)         g = atan2 (b, 2  * y / b);     else          g = atan2 (2  * (a * b - y) / a, a);     cout << setprecision (10 ) << fixed << g / PI * 180  << endl;     return  0 ; } 
题意:初始在 ( 0 , 0 ) (0,0) ( 0 , 0 ) ( 1 , 2 ) (1,2) ( 1 , 2 ) ( 2 , 1 ) (2,1) ( 2 , 1 ) ( X , Y ) (X,Y) ( X , Y ) 
 
解方程组 { 2 p + q = Y p + 2 q = Y \begin{cases}2p+q=Y\\p+2q=Y\end{cases} { 2 p + q = Y p + 2 q = Y  ( p + q q ) \begin{pmatrix}p+q\\q\end{pmatrix} ( p + q q  ) 
By antontrygubO_o 
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 const  int  N = 2e6 ;vector<int > facs (N)  ;vector<int > invfacs (N)  ;void  init ()     facs[0 ] = 1 ;     for  (int  i = 1 ; i<N; i++) facs[i] = mul (facs[i-1 ], i);     invfacs[N-1 ] = inv (facs[N-1 ]);     for  (int  i = N-2 ; i>=0 ; i--) invfacs[i] = mul (invfacs[i+1 ], i+1 ); } int  main ()      ios_base::sync_with_stdio (0 );     cin.tie (nullptr );     init ();     int  x, y;     cin>>x>>y;     if  ((x+y)%3 ) {cout<<0 ; return  0 ;}     int  n = (x+y)/3 ;     x-=n;     y-=n;     if  (x<0 ||y<0 ) {cout<<0 ; return  0 ;}     cout<<mul (facs[n], mul (invfacs[x], invfacs[y])); } 
题意:一棵 n n n 
 
贪心,DFS 时传入与父节点连的边的颜色,与儿子节点之间涂色时从小到大涂色,并刻意避开该颜色即可。
By sky58 
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 vector<pint> gr[100100 ]; int  col=0 ;int  out[100100 ];void  dfs (int  v,int  u,int  c)     int  ne=1 ;     rep (i,gr[v].size ()){         pint p=gr[v][i];         if (p.fi==u) continue ;         if (ne==c) ne++;         out[p.se]=ne;         dfs (p.fi,v,ne);         ne++;     } } int  main ()     int  n,a,b;     cin>>n;     rep (i,n-1 ){         cin>>a>>b;gr[a].pb (mp (b,i));gr[b].pb (mp (a,i));     }     REP (i,1 ,n+1 ) col=max (col,(int )gr[i].size ());     dfs (1 ,0 ,0 );     cout<<col<<endl;     rep (i,n-1 ) cout<<out[i]<<endl; } 
注意到使用的颜色个数一定为最大的节点度数,而在此前提下不一定每个点的边颜色最小,只要互不相同即可。又可以发现,连续 ≤ k \le k ≤ k % k \% k % k k k k 
By hitonanode 
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 vector<set<int >> e; map<pint, int > ma; void  dfs (int  now, int  prv, int  cnow)     ma[pint (now, prv)] = ma[pint (prv, now)] = cnow++;     for  (auto  nxt : e[now]) if  (nxt != prv)     {         dfs (nxt, now, cnow++);     } } int  main ()     lint N;     cin >> N;     e.resize (N);     vector<pint> p;     REP (i, N - 1 )     {         int  a, b;         cin >> a >> b;         a--, b--;         e[a].insert (b);         e[b].insert (a);         p.emplace_back (a, b);     }     int  c = 0 ;     REP (i, N) mmax (c, (int )e[i].size ());     dfs (0 , -1 , 0 );     printf ("%d\n" , c);     for  (auto  pa : p) printf ("%d\n" , ma[pa] % c + 1 ); } 
题意:给你一个序列 a a a ∑ i = 1 n − 1 ∑ j = i + 1 n a i  xor  a j \sum\limits_{i=1}^{n-1}\sum\limits_{j=i+1}^n a_i \text{ xor } a_j i = 1 ∑ n − 1  j = i + 1 ∑ n  a i   xor  a j  
 
对于每一位分开处理,考虑这一位在多少项里为 1 1 1 1 1 1 c n t cnt c n t 1 1 1 c n t ( n − c n t ) cnt(n-cnt) c n t ( n − c n t ) 
By jiangly 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include  <bits/stdc++.h>  using  namespace  std;constexpr  int  P = 1'000'000'007 ;int  main ()      ios::sync_with_stdio (false );     cin.tie (nullptr );     int  n;     cin >> n;     vector<long  long > a (n)  ;     for  (int  i = 0 ; i < n; ++i)         cin >> a[i];     int  ans = 0 ;     for  (int  k = 0 ; k < 60 ; ++k) {         int  c[2 ] = {};         for  (int  i = 0 ; i < n; ++i)             ++c[a[i] >> k & 1 ];         ans = (ans + (1LL  << k) % P * c[0 ] % P * c[1 ]) % P;     }     cout << ans << endl;     return  0 ; } 
题意:给你一个长度为 n n n a a a K K K K K K 1 1 1 K K K 
 
一位一位一次考虑即可。对于每一位,在能选的情况下显然应该贪心地选最靠前的那个。
By cjy 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <cstdio>  #include <cstring>  #include <algorithm>  using  namespace  std;int  n,a,last;int  main ()     scanf ("%d" ,&n);     for (int  i=1 ;i<=n;++i)     {         scanf ("%d" ,&a);         if (a==last+1 )++last;     }     if (!last)printf ("-1" );     else  printf ("%d" ,n-last);     return  0 ; } 
题意:给你一个长度为 n n n 
 
先求出总的方案数,再对于每个 k k k O ( 1 ) O(1) O ( 1 ) 
By kotatsugame 
1 2 3 4 5 6 n=read () for (i=0 ;i<n;i++){    x[i]=read ()     ans+=c[x[i]]++ } for (i=0 ;i<n;i++)ans-c[x[i]]+1 
题意:有 n n n i < n i<n i < n i ∼ i + 1 i\sim i+1 i ∼ i + 1 X ∼ Y X\sim Y X ∼ Y 1 ≤ K < n 1\le K<n 1 ≤ K < n K K K 
 
n 2 n^2 n 2 
By kotatsugame 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <iostream>  using  namespace  std;int  N,X,Y;int  cnt[2020 ];main (){     cin>>N>>X>>Y;     X--,Y--;     for (int  i=0 ;i<N;i++)     {         for (int  j=i+1 ;j<N;j++)         {             cnt[min (j-i,abs (X-i)+1 +abs (Y-j))]++;         }     }     for (int  k=1 ;k<N;k++)cout<<cnt[k]<<endl; } 
题意:定义一个数为 Lunlun Number,当且仅当这个数十进制下的相邻两位相差不超过 1 1 1 K K K 
 
直接暴力转移 K K K + 1 +1 + 1 
By myself 
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 #include <bits/stdc++.h>  using  namespace  std;signed  main ()      int  k;     cin>>k;     k--;     vector<int > now;     now.push_back (1 );     while (k--) {         bool  flag=0 ;         for (int  i=0 ;i<now.size ();i++)             if ((i==now.size ()-1 ||now[i]<=now[i+1 ])&&now[i]!=9 ) {                 now[i]++,flag=1 ;                 for (int  j=i-1 ;j>=0 ;j--)                     now[j]=max (0 ,now[j+1 ]-1 );                 break ;             }         if (!flag) {             now.push_back (1 );             for (int  i=0 ;i<now.size ()-1 ;i++)                 now[i]=0 ;         }     }     for (int  i=now.size ()-1 ;i>=0 ;i--)         cout<<now[i];     cout<<endl;     return  0 ; } 
从 1~9 开始 BFS,每次从一个数往后搜,即十进制下左移一位,再将最后一位考虑上三种可能性(− 1 , 0 , + 1 -1,0,+1 − 1 , 0 , + 1 K K K 
By SSRS 
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 #include  <bits/stdc++.h>  using  namespace  std;int  main ()   int  K;   cin >> K;   queue<long  long > Q;   for  (int  i = 1 ; i <= 9 ; i++){     Q.push (i);   }   while  (true ){     long  long  x = Q.front ();     Q.pop ();     K--;     if  (K == 0 ){       cout << x << endl;       break ;     }     int  r = x % 10 ;     if  (r != 0 ){       Q.push (x * 10  + r - 1 );     }     Q.push (x * 10  + r);     if  (r != 9 ){       Q.push (x * 10  + r + 1 );     }   } } 
可以使用 DFS 搜出范围内所有的解,再将所有解排序,输出第 K K K 
By risujiroh 
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 #include  <bits/stdc++.h>  using  namespace  std;int  main ()    cin.tie (nullptr );   ios::sync_with_stdio (false );   int  k;   cin >> k;   --k;   vector<long  long > a;   string s;   auto  dfs = [&](auto && self) -> void  {     if  (not  s.empty ()) {       a.push_back (stoll (s));     }     if  (s.size () == 10 ) {       return ;     }     if  (s.empty ()) {       for  (char  c = '1' ; c <= '9' ; ++c) {         s += c;         self (self);         s.pop_back ();       }     } else  {       for  (char  c = '0' ; c <= '9' ; ++c) {         if  (abs (c - s.back ()) <= 1 ) {           s += c;           self (self);           s.pop_back ();         }       }     }   };   dfs (dfs);   sort (begin (a), end (a));   cout << a[k] << '\n' ; } 
此做法与 BFS 的区别在于,BFS 保证了搜索顺序从小到大,找到第 K K K 
题意:有一个由 RGB 组成的字符串,问有多少个三元组 ( i , j , k ) (i,j,k) ( i , j , k ) k − j ≠ j − i k-j\ne j-i k − j  = j − i s i ≠ s j ≠ s k s_i\ne s_j\ne s_k s i   = s j   = s k  
 
对于每个位置考虑计算它作为 j j j 
By kotatsugame 
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 #include <iostream>  using  namespace  std;string s; long  ans;int  N;int  id (char  c) return  c=='R' ?0 :c=='G' ?1 :2 ;}main (){     cin>>N>>s;     for (int  i=0 ;i<N;i++)     {         long  L[3 ]={},R[3 ]={};         for (int  j=i-1 ;j>=0 ;j--)L[id (s[j])]++;         for (int  j=i+1 ;j<N;j++)R[id (s[j])]++;         for (int  j=0 ;j<3 ;j++)for (int  k=0 ;k<3 ;k++)         {             if (id (s[i])!=j&&id (s[i])!=k&&j!=k)ans+=L[j]*R[k];         }         for (int  k=1 ;;k++)         {             if (i-k<0 ||i+k>=N)break ;             if (s[i-k]!=s[i]&&s[i]!=s[i+k]&&s[i-k]!=s[i+k])ans--;         }     }     cout<<ans<<endl; } 
题意:每次操作可以将一个数 × a \times a × a 1 1 1 n n n 
 
BFS 搜索即可。
By heno239 
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 void  solve ()      ll a, n; cin >> a >> n;     ll sz = 1 ;     while  (sz <= n)sz *= 10 ;     vector<int > dist (sz, mod)  ;     queue<int > q;     q.push (1 );     dist[1 ] = 0 ;     while  (!q.empty ()) {         ll x = q.front (); q.pop ();         int  nd = dist[x] + 1 ;         if  (x * a < sz) {             if  (nd < dist[x * a]) {                 dist[x * a] = nd;                 q.push (x * a);             }         }         if  (x >= 10  && x % 10 ) {             string s = to_string (x);             s.insert (s.begin (), s.back ());             s.pop_back ();             int  nx = stoi (s);             if  (nd < dist[nx]) {                 dist[nx] = nd;                 q.push (nx);             }         }     }     int  ans = dist[n];     if  (ans == mod)ans = -1 ;     cout << ans << "\n" ; } signed  main ()      ios::sync_with_stdio (false );     cin.tie (0 );     cout << fixed << setprecision (10 );                              solve ();     return  0 ; } 
题意:有 2 n 2n 2 n 
 
暴搜即可。每次搜的时候考虑第一个没选的人选谁。
By tourist 
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 #include  <bits/stdc++.h>  using  namespace  std;#ifdef  LOCAL #include  "algo/debug.h"  #else  #define  debug(...) 42 #endif  int  main ()    ios::sync_with_stdio (false );   cin.tie (0 );   int  n;   cin >> n;   vector<vector<int >> a (2  * n, vector<int >(2  * n));   for  (int  i = 0 ; i < 2  * n; i++) {     for  (int  j = i + 1 ; j < 2  * n; j++) {       cin >> a[i][j];     }   }   vector<bool > used (2  * n, false )  ;   int  ans = 0 ;   function<void int )> Dfs = [&](int  w) {     int  i = 0 ;     while  (i < 2  * n && used[i]) {       ++i;     }     if  (i == 2  * n) {       ans = max (ans, w);       return ;     }     for  (int  j = i + 1 ; j < 2  * n; j++) {       if  (!used[j]) {         used[i] = used[j] = true ;         Dfs (w ^ a[i][j]);         used[i] = used[j] = false ;       }     }   };   Dfs (0 );   cout << ans << '\n' ;   return  0 ; } 
题意:你需要用 s 1 ∼ s n s_1\sim s_n s 1  ∼ s n  n n n n n n [ 3 , 16 ] [3,16] [ 3 , 1 6 ] 
 
直接 DFS,每次新加入一个 s s s 
By heno239 
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 void  solve ()      int  n; cin >> n;     int  m; cin >> m;     vector<string> s (n)  ;     rep (i, n)cin >> s[i];     set<string> st;     rep (i, m) {         string t; cin >> t; st.insert (t);     }     string ans="-1" ;     string cur;     vector<bool > used (n)  ;     function<bool          if  (cur.size () > 16 )return  false ;         bool  valid = false ;         if  (cur.size () >= 3 ) {             valid = true ;             rep (i, n)if  (!used[i])valid = false ;             if  (st.count (cur))valid = false ;             if  (cur.back () == '_' )valid = false ;         }         if  (valid) {             ans = cur; return  true ;         }         if  (cur.size ()) {             cur.push_back ('_' );             if  (dfs ())return  true ;             cur.pop_back ();         }         if  (cur.empty ()||cur.back ()== '_' ) {             rep (i, n)if  (!used[i]) {                 string cop = cur;                 cur += s[i];                 used[i] = true ;                 if  (dfs ())return  true ;                 cur = cop;                 used[i] = false ;             }         }         return  false ;     };     dfs ();     cout << ans << "\n" ; } signed  main ()      ios::sync_with_stdio (false );     cin.tie (0 );          init_f ();                         solve ();     return  0 ; } 
题意:对于一个坐标,称它上、下、左、右、左下、右下方的坐标与它相临。给你若干个坐标,判断有几个连通块。
 
n 2 n^2 n 2 
By SSRS 
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 #include  <bits/stdc++.h>  using  namespace  std;vector<int > dx = {-1 , -1 , 0 , 0 , 1 , 1 }; vector<int > dy = {-1 , 0 , -1 , 1 , 0 , 1 }; int  main ()   int  N;   cin >> N;   vector<int > X (N) , Y (N)  ;   for  (int  i = 0 ; i < N; i++){     cin >> X[i] >> Y[i];   }   map<pair<int , int >, int > mp;   for  (int  i = 0 ; i < N; i++){     mp[make_pair (X[i], Y[i])] = i;   }   vector<bool > used (N, false )  ;   int  ans = 0 ;   for  (int  i = 0 ; i < N; i++){     if  (!used[i]){       used[i] = true ;       queue<int > Q;       Q.push (i);       while  (!Q.empty ()){         int  v = Q.front ();         Q.pop ();         for  (int  j = 0 ; j < 6 ; j++){           int  x = X[v] + dx[j];           int  y = Y[v] + dy[j];           if  (mp.count (make_pair (x, y)) == 1 ){             int  w = mp[make_pair (x, y)];             if  (!used[w]){               used[w] = true ;               Q.push (w);             }           }         }       }       ans++;     }   }   cout << ans << endl; } 
题意:有一个栈,栈中元素为 0 ∼ 9 0\sim 9 0 ∼ 9 ( m o d 10 ) \pmod{10} ( m o d 1 0 ) i ∈ [ 0 , 9 ] i\in [0,9] i ∈ [ 0 , 9 ] i i i 
 
由于每次操作不确定的值仅为栈顶元素,考虑 f [ i ] [ j ∈ [ 0 , 9 ] ] f[i][j\in[0,9]] f [ i ] [ j ∈ [ 0 , 9 ] ] i i i j j j 
f [ i ] [ j ] = ∑ k × a i + 1   m o d   10   =   j f [ i − 1 ] [ k ] + ∑ k + a i + 1   m o d   10   =   j f [ i − 1 ] [ k ] f[i][j]=\sum\limits_{k\times a_{i+1}\bmod 10\ =\ j} f[i-1][k]+\sum\limits_{k+a_{i+1}\bmod 10\ =\ j} f[i-1][k]
 f [ i ] [ j ] = k × a i + 1  m o d 1 0   =   j ∑  f [ i − 1 ] [ k ] + k + a i + 1  m o d 1 0   =   j ∑  f [ i − 1 ] [ k ] 
使用刷表法可以将转移优化成 O ( 1 ) O(1) O ( 1 ) 
{ f [ i + 1 ] [ j × a i + 2   m o d   10 ]  +=  f [ i ] [ j ] , f [ i + 1 ] [ j + a i + 2   m o d   10 ]  +=  f [ i ] [ j ] \begin{cases}
f[i+1][j\times a_{i+2}\bmod 10]\text{ += }f[i][j],\\
f[i+1][j+a_{i+2}\bmod 10]\text{ += }f[i][j]
\end{cases}
 { f [ i + 1 ] [ j × a i + 2  m o d 1 0 ]  +=  f [ i ] [ j ] , f [ i + 1 ] [ j + a i + 2  m o d 1 0 ]  +=  f [ i ] [ j ]  
By jiangly 
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 int  main ()      std::ios::sync_with_stdio (false );     std::cin.tie (nullptr );     int  N;     std::cin >> N;     Z f[10 ];     int  A0;     std::cin >> A0;     f[A0] = 1 ;     for  (int  i = 1 ; i < N; i++) {         int  x;         std::cin >> x;         Z g[10 ];         for  (int  y = 0 ; y < 10 ; y++) {             g[x * y % 10 ] += f[y];             g[(x + y) % 10 ] += f[y];         }         std::copy (g, g + 10 , f);     }     for  (int  i = 0 ; i < 10 ; i++) {         std::cout << f[i].val () << "\n" ;     }     return  0 ; } 
题意:有一个 n × m n\times m n × m # 为墙、. 为空地。从左上角开始,每次只能往右或往下走,求最长路经。
 
设 f [ i ] [ j ] f[i][j] f [ i ] [ j ] ( i , j ) (i,j) ( i , j ) ( i , j ) (i,j) ( i , j ) − i n f -\mathrm{inf} − i n f f [ i ] [ j ] = max  ( f [ i − 1 ] [ j ] , f [ i ] [ j − 1 ] ) + 1 f[i][j]=\max(f[i-1][j],f[i][j-1])+1 f [ i ] [ j ] = max ( f [ i − 1 ] [ j ] , f [ i ] [ j − 1 ] ) + 1 
By natsugiri 
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 int  H, W;char  C[111 ][111 ];int  D[111 ][111 ];void  MAIN ()      scanf ("%d%d" , &H, &W);     REP  (i, H) scanf ("%s" , C[i]);     memset (D, 0xc0 , sizeof  D);     D[0 ][0 ] = 1 ;     int  ans = 1 ;     REP  (i, H) REP  (j, W) if  (C[i][j] == '.' ) {     if  (i) amax (D[i][j], D[i-1 ][j]+1 );     if  (j) amax (D[i][j], D[i][j-1 ]+1 );     amax (ans, D[i][j]);     }     printf ("%d\n" , ans); } int  main ()      int  TC = 1 ;     REP  (tc, TC) MAIN ();     return  0 ; } 
令 f [ i ] [ j ] f[i][j] f [ i ] [ j ] ( i , j ) (i,j) ( i , j ) f [ i ] [ j ] = { 0 ,   if  ( i , j )  is a space m a x ( f [ i + 1 ] [ j ] , f [ i ] [ j + 1 ] ) + 1 , otherwise f[i][j]=\begin{cases}0,\ \text{ if }(i,j) \text{ is a space}\\max(f[i+1][j],f[i][j+1])+1, \text{otherwise}\end{cases} f [ i ] [ j ] = { 0 ,    if  ( i , j )  is a space m a x ( f [ i + 1 ] [ j ] , f [ i ] [ j + 1 ] ) + 1 , otherwise  
这样可以使有墙的情况的处理更加简洁。
By tourist 
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 #include  <bits/stdc++.h>  using  namespace  std;int  main ()    ios::sync_with_stdio (false );   cin.tie (0 );   int  h, w;   cin >> h >> w;   vector<string> g (h)  ;   for  (int  i = 0 ; i < h; i++) {     cin >> g[i];   }   vector<vector<int >> f (h, vector<int >(w));   for  (int  i = h - 1 ; i >= 0 ; i--) {     for  (int  j = w - 1 ; j >= 0 ; j--) {       if  (g[i][j] == '#' ) {         f[i][j] = 0 ;       } else  {         f[i][j] = 1 ;         if  (i + 1  < h && g[i + 1 ][j] == '.' ) {           f[i][j] = max (f[i][j], f[i + 1 ][j] + 1 );         }         if  (j + 1  < w && g[i][j + 1 ] == '.' ) {           f[i][j] = max (f[i][j], f[i][j + 1 ] + 1 );         }       }     }   }   cout << f[0 ][0 ] << '\n' ;   return  0 ; }