hpu萌新训练赛(三)

打印 上一主题 下一主题

主题 1789|帖子 1789|积分 5367

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
集合
直接埃氏筛,边筛边合并就行。留意先 ans = b - a + 1 然后再计算。 分别是 j 和 j - i 这两个数来举行计算。
代码
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using i64 = long long;
  4. typedef pair<int, int> PII;
  5. bool st[100005];
  6. int f[100005];
  7. int find(int x)
  8. {
  9.         if (x != f[x]) f[x] = find(f[x]);
  10.         return f[x];
  11. }
  12. int main()
  13. {
  14.         int a, b, p; scanf("%d%d%d", &a, &b, &p);
  15.         int ans = b - a + 1;
  16.         for (int i = a; i <= b; i ++) f[i] = i;
  17.         for (int i = 2; i <= b; i ++)
  18.         {
  19.                 if (!st[i])
  20.                 {
  21.                         if (i >= p)
  22.                         for (int j = i + i; j <= b; j += i) // j 和 j - i 是两个数,他们两个都有 i 这个质数。
  23.                         {
  24.                                 st[j] = true;
  25.                                 if (j - i >= a && find(j) != find(j - i))
  26.                                 {
  27.                                         int fa = find(j), fb = find(j-i);
  28.                                         f[fa] = fb;
  29.                                         ans --;
  30.                                 }
  31.                         }
  32.                         else for (int j = i + i; j <= b; j += i)
  33.                         st[j] = true;
  34.                 }
  35.         }
  36.        
  37.         printf("%d", ans);
  38.         return 0;
  39. }
复制代码
迷宫寻路
这个是一道非常典型的 dfs 题目。
走过的记得更新为 # 即可。
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using i64 = long long;
  4. typedef pair<int, int> PII;
  5. constexpr int N = 110;
  6. char g[N][N];
  7. int dx[] = {0, 0, -1, 1}, dy[] = {1, -1, 0, 0};
  8. int n, m;
  9. int ans;
  10. int cnt;
  11. void dfs(int x, int y)
  12. {
  13.         if (x == n && y == m)
  14.         {
  15.                 ans = 1;
  16.                 return;
  17.         }
  18.         g[x][y] = '#';
  19.         // // cnt++;
  20.         // if (cnt > 1e5)
  21.         // {
  22.         //         ans = 1e9;
  23.         //         return;
  24.         // }
  25.         for (int i = 0; i < 4; i++)
  26.         {
  27.                 int ux = x + dx[i], uy = y + dy[i];
  28.                 if (ux > n || ux < 1 || uy > m || uy < 1 || g[ux][uy] == '#')
  29.                         continue;
  30.                 dfs(ux, uy);
  31.         }
  32. }
  33. void solve()
  34. {
  35.         scanf("%d%d", &n, &m);
  36.         for (int i = 1; i <= n; i++)
  37.                 for (int j = 1; j <= m; j++)
  38.                 {
  39.                         char ch;
  40.                         cin >> ch;
  41.                         g[i][j] = ch;
  42.                 }
  43.         dfs(1, 1);
  44.         if (ans == 1)
  45.         {
  46.                 printf("Yes");
  47.         }
  48.         else
  49.                 printf("No");
  50. }
  51. signed main()
  52. {
  53.         int _ = 1;
  54.         // cin >> t;
  55.         while (_--)
  56.         {
  57.                 solve();
  58.         }
  59.         return 0;
  60. }
复制代码
P1464 Function
这个题目用到了影象化搜索的方法。假如我已经计算过 w(a, b, c) 了,那我就把他存下来,如许以后就不需要再举行重复计算了。
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using i64 = long long;
  4. typedef pair<int, int> PII;
  5. int dp[25][25][25];
  6. i64 w(i64 a, i64 b, i64 c)
  7. {
  8.   if (a <= 0 || b <= 0 || c <= 0) return 1;
  9.   if (a > 20 || b > 20 || c > 20)
  10.   {
  11.     if (dp[20][20][20]) return dp[20][20][20];
  12.     dp[20][20][20] = w(20, 20, 20);  
  13.     return dp[20][20][20];
  14.   }
  15.   if (a < b && b < c)
  16.   {
  17.     if (dp[a][b][c]) return dp[a][b][c];
  18.     if (!dp[a][b][c - 1]) dp[a][b][c - 1] = w(a, b, c - 1);
  19.     if (!dp[a][b - 1][c - 1]) dp[a][b - 1][c - 1] = w(a, b - 1, c - 1);
  20.     if (!dp[a][b - 1][c]) dp[a][b - 1][c] = w(a, b - 1, c);
  21.     dp[a][b][c] = dp[a][b][c - 1] + dp[a][b - 1][c - 1] - dp[a][b - 1][c];
  22.     return dp[a][b][c];
  23.   }
  24.   if (!dp[a-1][b][c]) dp[a-1][b][c] = w(a - 1, b, c);
  25.   if (!dp[a-1][b-1][c]) dp[a-1][b-1][c] = w(a-1, b-1, c);
  26.   if (!dp[a-1][b][c-1]) dp[a-1][b][c-1] = w(a-1, b, c-1);
  27.   if (!dp[a-1][b-1][c-1]) dp[a-1][b-1][c-1]=w(a - 1, b - 1, c - 1);
  28.   return dp[a-1][b][c] + dp[a-1][b-1][c] + dp[a-1][b][c-1] - dp[a-1][b-1][c-1];
  29. }
  30. int main()
  31. {
  32.   i64 a, b, c;
  33.   while (cin >> a >> b >> c)
  34.   {
  35.     if (a == -1 && b == -1 && c == -1)
  36.     {
  37.       return 0;
  38.     }
  39.     printf("w(%lld, %lld, %lld) = %d\n", a, b, c, w(a, b, c));
  40.   }
  41.   return 0;
  42. }
复制代码
P1009 [NOIP 1998 普及组] 阶乘之和
这个题目用到了一个东西叫做大数,也叫高精度。可以用 c++ 代码实现,也可以用 python 来实现。python 来实现比较简单一点。
  1. n = int(input())
  2. x = 1
  3. ans = 0
  4. for i in range(1, n + 1):
  5.     x *= i
  6.     ans += x
  7. print(ans)
复制代码
P1496 火烧赤壁
这个题目用到了离散化和差分。
  1. #include <bits/stdc++.h>
  2. using i64 = long long;
  3. using namespace std;
  4. typedef pair<int, int> PII;
  5. vector<int> id;
  6. int get(int x)
  7. {
  8.   return lower_bound(id.begin(), id.end(), x) - id.begin() + 1;
  9. }
  10. /*
  11. 把数映射到另一个东西里面
  12. */
  13. void solve()
  14. {
  15.   int n;
  16.   scanf("%d", &n);
  17.   int mmax = -1, mmin = 2e9;
  18.   map<i64, i64> c;
  19.   vector<PII> cor;
  20.   for (int i = 0; i < n; i++)
  21.   {
  22.     int l, r;
  23.     scanf("%d%d", &l, &r);
  24.     id.push_back(l);
  25.     id.push_back(r);
  26.     cor.push_back({l, r});
  27.   }
  28.   sort(id.begin(), id.end());
  29.   id.erase(unique(id.begin(), id.end()), id.end());
  30.   for (auto [x, y] : cor)
  31.   {
  32.     int xx = get(x), yy = get(y);
  33.     c[xx] += 1, c[yy] -= 1;
  34.     mmin = min(mmin, xx);
  35.     mmax = max(mmax, yy);
  36.   }
  37.   for (int i = mmin; i < mmax; i++)
  38.   {
  39.     c[i] += c[i - 1];
  40.     // cout<<c[i]<<' ';
  41.   }
  42.   // printf("mmin = %d mmax = %d", mmin, mmax);
  43.   int ans = 0,l=0,r=0;
  44.   while(r<mmax){
  45.     while(l<mmax && c[l]==0)l++,r++;
  46.     while(r<mmax && c[r]!=0)r++;
  47.     int ln=id[l-1],rn=id[r-1];
  48.     ans+=(rn-ln);
  49.     // printf("l = %d r = %d\n", l, r);
  50.     l = r;
  51.   }
  52.   cout << ans<<'\n';
  53. }
  54. signed main()
  55. {
  56.   int t = 1;
  57.   // cin >> t;
  58.   while (t--)
  59.   {
  60.     solve();
  61.   }
  62.   return 0;
  63. }
复制代码
P1469 找筷子
这个题目用到了异或的一个性子,对一个数同时异或两次的话这个数就相当于没有异或。所以直接默认一开始为 0 ,然后不停异或就行了。
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef pair<int, int> PII;
  4. typedef long long i64;
  5. void solve()
  6. {
  7.   int n; scanf("%d", &n);
  8.   int x = 0;
  9.   for (int i = 0; i < n; i++)
  10.   {
  11.     int u; scanf("%d", &u);
  12.     x ^= u;
  13.   }
  14.   cout << x;
  15. }
  16. signed main()
  17. {
  18.   int t = 1;
  19.   // cin >> t;
  20.   while (t--)
  21.   {
  22.     solve();
  23.   }
  24.   return 0;
  25. }
复制代码
P2626 斐波那契数列(升级版)
这个题目的关键在于分解质因数。求斐波那契数列的话,直接递推即可。
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using i64 = long long;
  4. typedef pair<int, int> PII;
  5. constexpr int N = 50 + 10;
  6. i64 f[N];
  7. const int M = 2147483648;
  8. void init()
  9. {
  10.         f[1] = 1;
  11.         f[2] = 1;
  12.         for (int i = 3; i <= 48; i++)
  13.                 f[i] = f[i - 1] + f[i - 2];
  14.         for (int i = 1; i <= 48; i++)
  15.         {
  16.                 f[i] %= M;
  17.         }
  18. }
  19. void solve()
  20. {
  21.         init();
  22.         // for (int i = 1; i <= 48; i ++)
  23.         // {
  24.         //         cout << f[i] << "\n";
  25.         // }
  26.         int n;
  27.         cin >> n;
  28.         i64 x = f[n];
  29.         map<int, int> mp;
  30.         int mmin = 2e9;
  31.         for (int i = 2; i * i <= x; i++)
  32.         {
  33.                 if (x % i == 0)
  34.                 {
  35.                         mmin = min(mmin, i);
  36.                         while (x % i == 0)
  37.                         {
  38.                                 mp[i]++;
  39.                                 x /= i;
  40.                         }
  41.                 }
  42.         }
  43.         if (x > 1)
  44.         {
  45.                 mmin = min(mmin, int(x));
  46.                 mp[x]++;
  47.         }
  48.         printf("%lld=", f[n]);
  49.         for (auto m : mp)
  50.         {
  51.                 if (m.first == mmin)
  52.                 {
  53.                         printf("%d", m.first);
  54.                         for (int i = 2; i <= m.second; i++)
  55.                                 printf("*%d", m.first);
  56.                 }
  57.                 else
  58.                         for (int i = 1; i <= m.second; i++)
  59.                                 printf("*%d", m.first);
  60.         }
  61. }
  62. signed main()
  63. {
  64.         int _ = 1;
  65.         // cin >> t;
  66.         while (_--)
  67.         {
  68.                 solve();
  69.         }
  70.         return 0;
  71. }
复制代码
P3879 [TJOI2010] 阅读明白
这个题目用到了 map<string, vector> 这个 stl 容器。会用这个容器的话然后举行一下去重就能做出来了。
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using i64 = long long;
  4. typedef pair<int, int> PII;
  5. int main()
  6. {
  7.   int n; scanf("%d", &n);
  8.   map<string, vector<int>> mp;
  9.   for (int i = 1; i <= n; i ++)
  10.   {
  11.     int x; scanf("%d", &x);
  12.     for (int j = 1; j <= x; j ++)
  13.     {
  14.       string u; cin >> u;
  15.       mp[u].push_back(i);
  16.     }
  17.   }
  18.   int m; scanf("%d", &m);
  19.   while (m --)
  20.   {
  21.     string s; cin >> s;
  22.     sort(mp[s].begin(), mp[s].end());
  23.     mp[s].erase(unique(mp[s].begin(), mp[s].end()), mp[s].end());
  24.     for (int i = 0; i < mp[s].size(); i ++)
  25.     {
  26.       printf("%d ", mp[s][i]);
  27.     }
  28.     printf("\n");
  29.   }
  30.   return 0;
  31. }
复制代码
P1024 [NOIP 2001 提高组] 一元三次方程求解
这个题目直接暴力就行了,不外是浮点数暴力,每次加上 0.01 然后判定这个答案行不可。
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using i64 = long long;
  4. typedef pair<int, int> PII;
  5. double a, b, c, d;
  6. double ck(double x)
  7. {
  8.         double l = x - 0.001, r = x + 0.001;
  9.         if ((a * pow(r, 3) + b * pow(r, 2) + r*c + d < 0) && (a * pow(l, 3) + b * pow(l, 2) + c * l + d > 0) ||(a * pow(r, 3) + b * pow(r, 2) + r*c + d > 0) && (a * pow(l, 3) + b * pow(l, 2) + c * l + d < 0))
  10.                 return true;
  11.         return false;
  12. }
  13. void solve()
  14. {
  15.         cin >> a >> b >> c >> d;
  16.         for (double i = -100.0; i <= 100.0; i += 0.01)
  17.         {
  18.                 if (ck(i))
  19.                 printf("%.2lf ", i);
  20.         }
  21. }
  22. signed main()
  23. {
  24.         int _ = 1;
  25.         // cin >> t;
  26.         while (_--)
  27.         {
  28.                 solve();
  29.         }
  30.         return 0;
  31. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

莫张周刘王

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表