• AtCoder Beginner Contest 233 (A-Ex)


    A.根据题意模拟即可

    B.根据题意模拟即可

    C.直接用map 进行dp即可

    D.用前缀和进行模拟,用map统计前缀和,每次计算当前前缀和-k的个数就是以当前点为右端点答案。

    E - Σ[k=0..10^100]floor(X/10^k) (atcoder.jp)

            (1)题意

            (2)思路

                    手动推一下这个东西就会发现,其实每一位上的贡献等于这一位后面的所有数加起来,因此做一个后缀和即可。

            (3)代码

    1. #include
    2. #define rep(i,z,n) for(int i = z;i <= n; i++)
    3. #define per(i,n,z) for(int i = n;i >= z; i--)
    4. #define PII pair
    5. #define fi first
    6. #define se second
    7. #define vi vector
    8. #define vl vector
    9. #define pb push_back
    10. #define sz(x) (int)x.size()
    11. #define all(x) (x).begin(),(x).end()
    12. using namespace std;
    13. using ll = long long;
    14. const int N = 5e5 + 10;
    15. ll Ans[N],suf[N];
    16. void solve()
    17. {
    18. string x;
    19. cin >> x;
    20. reverse(all(x));
    21. for(int i = sz(x) - 1;i >= 0;i --) suf[i] = suf[i + 1] + (x[i] - '0');
    22. for(int i = 0;i < sz(x);i ++) {
    23. Ans[i] = suf[i];
    24. }
    25. for(int i = 0;i < 500001;i ++) {
    26. Ans[i + 1] += Ans[i] / 10;
    27. Ans[i] %= 10;
    28. }
    29. int r = 500001;
    30. while(Ans[r] == 0) r --;
    31. while(r >= 0) cout << Ans[r --];
    32. }
    33. int main()
    34. {
    35. ios::sync_with_stdio(false);
    36. cin.tie(0),cout.tie(0);
    37. int T = 1;
    38. // cin >> T;
    39. while(T --) solve();
    40. return 0;
    41. }

    F - Swap and Sort (atcoder.jp)

            (1)题意

                    有一个排列P,给出M组交换关系,第i组swap(Pai,Pbi),问是否有可能可以使P不降。

            (2)思路

                    首先,若i和P[i]不在一个连通块,则一定不会交换成功,然后考虑如何交换,对于度数为1的点说明我们此时交换掉他并且不会影响后继,因此满足拓扑排序,那么我们直接根据拓扑排序进行交换即可。

            (3)代码

    1. #include
    2. #define rep(i,z,n) for(int i = z;i <= n; i++)
    3. #define per(i,n,z) for(int i = n;i >= z; i--)
    4. #define PII pair
    5. #define fi first
    6. #define se second
    7. #define vi vector
    8. #define vl vector
    9. #define pb push_back
    10. #define sz(x) (int)x.size()
    11. #define all(x) (x).begin(),(x).end()
    12. using namespace std;
    13. using ll = long long;
    14. const int N = 2e5 + 10;
    15. struct DSU {
    16. vector<int> f,siz;
    17. int n;
    18. DSU(int _n) {
    19. n = _n;
    20. f.resize(n + 1);
    21. siz.resize(n + 1,1);
    22. iota(f.begin(),f.end(),0);
    23. }
    24. inline int find(int x) {
    25. if(x == f[x]) return x;
    26. return f[x] = find(f[x]);
    27. }
    28. inline bool same(int x,int y) {
    29. x = find(x),y = find(y);
    30. return x == y;
    31. }
    32. inline void merge(int x,int y) {
    33. if(same(x,y)) return ;
    34. x = find(x),y = find(y);
    35. siz[y] += siz[x];
    36. f[x] = y;
    37. }
    38. //目前连通块个数
    39. inline int connect() {
    40. int res = 0;
    41. for(int i = 1;i <= n;i ++) {
    42. res += (i == find(i));
    43. }
    44. return res;
    45. }
    46. //求某一个联通块得大小
    47. inline int count(int x) {
    48. x = find(x);
    49. return siz[x];
    50. }
    51. };
    52. int p[N],deg[N];
    53. vector e[N];
    54. vector<int> ans;
    55. inline bool dfs(int u,int f,int tar)
    56. {
    57. if(u == tar) return true;
    58. for(auto [v,id]: e[u]) {
    59. if(v == f) continue;
    60. if(dfs(v,u,tar)) {
    61. swap(p[u],p[v]);
    62. ans.pb(id);
    63. return true;
    64. }
    65. }
    66. return false;
    67. }
    68. void solve()
    69. {
    70. int n;
    71. cin >> n;
    72. rep(i,1,n) cin >> p[i];
    73. DSU dsu(n);
    74. int m;
    75. cin >> m;
    76. rep(i,1,m) {
    77. int u,v;
    78. cin >> u >> v;
    79. if(!dsu.same(u,v)) {
    80. dsu.merge(u,v);
    81. e[u].pb({v,i});
    82. e[v].pb({u,i});
    83. deg[u] ++,deg[v] ++;
    84. }
    85. }
    86. queue<int> q;
    87. rep(i,1,n) {
    88. if(!dsu.same(i,p[i])) {
    89. cout << -1 << '\n';
    90. return;
    91. }
    92. if(deg[i] == 1) q.push(i);
    93. }
    94. while(!q.empty()) {
    95. int v = q.front();
    96. q.pop();
    97. int tar = 0;
    98. for(int i = 1;i <= n;i ++) {
    99. if(p[i] == v) {
    100. tar = i;
    101. break;
    102. }
    103. }
    104. if(!dfs(v,0,tar)) {
    105. cout << -1 << '\n';
    106. return;
    107. }
    108. for(auto [u,id]: e[v]) {
    109. if(-- deg[u] == 1) q.push(u);
    110. }
    111. }
    112. cout << sz(ans) << '\n';
    113. for(auto x : ans) cout << x << ' ';
    114. }
    115. int main()
    116. {
    117. ios::sync_with_stdio(false);
    118. cin.tie(0),cout.tie(0);
    119. int T = 1;
    120. // cin >> T;
    121. while(T --) solve();
    122. return 0;
    123. }

    G - Strongest Takahashi (atcoder.jp)

            (1)题意

                    给你一个N*N的矩形,里面#代表的是障碍,.不是障碍,你每次可以选择一个D*D的矩形把里面的障碍清除掉会花费D,问你把N*N的障碍全部清除掉的最小花费是多少。

            (2)思路

                    很明显的一个思路是,这个可以分治进行dp,考虑dp[l1][r1][l2][r2]表示消除[l1-l2][r1-r2]这个矩形的最小花费,我们每一次可以枚举横着切下去还是竖着切下去就行,或者整个是正方形也可以直接清除,取个最小花费即可。

            (3)代码

    1. #include
    2. #define rep(i,z,n) for(int i = z;i <= n; i++)
    3. #define per(i,n,z) for(int i = n;i >= z; i--)
    4. #define PII pair
    5. #define fi first
    6. #define se second
    7. #define vi vector
    8. #define vl vector
    9. #define pb push_back
    10. #define sz(x) (int)x.size()
    11. #define all(x) (x).begin(),(x).end()
    12. using namespace std;
    13. using ll = long long;
    14. const int N = 55;
    15. int dp[N][N][N][N],s[N][N];
    16. string mp[N];
    17. const int inf = 0x3f3f3f3f;
    18. int get(int x1,int y1,int x2,int y2)
    19. {
    20. return s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1];
    21. }
    22. inline int dfs(int x1,int y1,int x2,int y2)
    23. {
    24. if(dp[x1][y1][x2][y2] != -1) return dp[x1][y1][x2][y2];
    25. if(get(x1,y1,x2,y2) == 0) return dp[x1][y1][x2][y2] = 0;
    26. int mi = inf;
    27. for(int i = x1 + 1;i <= x2;i ++) {
    28. mi = min(mi,dfs(x1,y1,i - 1,y2) + dfs(i,y1,x2,y2));
    29. }
    30. for(int i = y1 + 1;i <= y2;i ++) {
    31. mi = min(mi,dfs(x1,y1,x2,i - 1) + dfs(x1,i,x2,y2));
    32. }
    33. if(x2 - x1 == y2 - y1) mi = min(mi,x2 - x1 + 1);
    34. return dp[x1][y1][x2][y2] = mi;
    35. }
    36. void solve()
    37. {
    38. int n;
    39. cin >> n;
    40. memset(dp,-1,sizeof(dp));
    41. rep(i,1,n) {
    42. cin >> mp[i];
    43. mp[i] = " " + mp[i];
    44. rep(j,1,n) s[i][j] = s[i - 1][j] + s[i][j - 1] + (mp[i][j] == '#') - s[i - 1][j - 1];
    45. }
    46. cout << dfs(1,1,n,n);
    47. }
    48. int main()
    49. {
    50. ios::sync_with_stdio(false);
    51. cin.tie(0),cout.tie(0);
    52. int T = 1;
    53. // cin >> T;
    54. while(T --) solve();
    55. return 0;
    56. }

    Ex - Manhattan Christmas Tree (atcoder.jp)

            (1)题意

                    二维平面上有N棵圣诞树,第i棵位于[xi,yi],要回答一下Q个问题,第i个问题是,以曼哈顿距离为单位,(ai,bi)和距离该点最近的Ki棵圣诞树之间的距离是多少?

            (2)思路

                    考虑曼哈顿距离不好进行计算,因此转换成切比雪夫距离,源坐标系上(x,y)的曼哈顿距离等价于新坐标系上(x+y,x-y)的切比雪夫距离,(补充:源坐标系上(x,y)的切比雪夫距离等价于新坐标系上(\frac{x + y}{2},\frac{x - y}{2})的曼哈顿距离)看着切比雪夫距离,我们很容易想到直接二分距离,问题转变这个矩形平面内有多少点,也就是二维数点问题,因为点不是很稠密,我们考虑直接动态开点二维树状数组。

            (3)代码

    1. #include
    2. #define rep(i,z,n) for(int i = z;i <= n; i++)
    3. #define per(i,n,z) for(int i = n;i >= z; i--)
    4. #define PII pair
    5. #define fi first
    6. #define se second
    7. #define vi vector
    8. #define vl vector
    9. #define pb push_back
    10. #define sz(x) (int)x.size()
    11. #define all(x) (x).begin(),(x).end()
    12. using namespace std;
    13. using ll = long long;
    14. const int N = 5e5 + 10;
    15. vector<int> ver[N << 1];
    16. inline int lowbit(int x)
    17. {
    18. return x & (-x);
    19. }
    20. inline void add(int x,int y)
    21. {
    22. x += N,y += N;
    23. if(!y) y = 1;
    24. while(y < 2 * N) {
    25. ver[y].pb(x);
    26. y += lowbit(y);
    27. }
    28. }
    29. inline int get(int y,int x1,int x2)
    30. {
    31. int Ans = 0;
    32. y += N,x1 += N,x2 += N;
    33. if(y >= 2 * N) y = 2 * N - 1;
    34. while(y > 0) {
    35. Ans += upper_bound(all(ver[y]),x2) - lower_bound(all(ver[y]),x1);
    36. y -= lowbit(y);
    37. }
    38. return Ans;
    39. }
    40. inline int query(int x1,int y1,int x2,int y2)
    41. {
    42. return get(y2,x1,x2) - get(y1 - 1,x1,x2);
    43. }
    44. void solve()
    45. {
    46. vector point;
    47. int n;
    48. cin >> n;
    49. rep(i,1,n) {
    50. int x,y;
    51. cin >> x >> y;
    52. point.pb({x + y,x - y});
    53. }
    54. sort(all(point));
    55. for(auto [x,y]: point) add(x,y);
    56. int q;
    57. cin >> q;
    58. while(q --) {
    59. int x,y,k;
    60. cin >> x >> y >> k;
    61. int z = x;
    62. x = z + y,y = z - y;
    63. int l = 0,r = N;
    64. while(l <= r) {
    65. int m = (l + r) >> 1;
    66. if(query(x - m,y - m,x + m,y + m) < k) l = m + 1;
    67. else r = m - 1;
    68. }
    69. cout << l << '\n';
    70. }
    71. }
    72. int main()
    73. {
    74. ios::sync_with_stdio(false);
    75. cin.tie(0),cout.tie(0);
    76. int T = 1;
    77. // cin >> T;
    78. while(T --) solve();
    79. return 0;
    80. }

  • 相关阅读:
    关于 obdeploy 部署脚本中的 Oceanbase 相关密码的理解
    java-String原理-创建对象的个数
    C++——继承
    CentOS 7.9.2009 数据盘挂载
    机器学习实战 | SKLearn最全应用指南
    新库上线 | CnOpenDataA股上市公司基本信息数据
    JAVA-WEB项目中,前后台结合AES和RSA对数据加密处理
    2023年初中生古诗文大会初选正在进行中,详细参赛流程和实用建议
    Deque容器的系列操作( 详解 )
    WordPress 博客实现登录后台邮件提醒的教程
  • 原文地址:https://blog.csdn.net/scanner___yw/article/details/133544615