Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >程序员进阶之算法练习(一百)

程序员进阶之算法练习(一百)

作者头像
落影
发布于 2024-03-08 23:57:52
发布于 2024-03-08 23:57:52
11700
代码可运行
举报
文章被收录于专栏:落影的专栏落影的专栏
运行总次数:0
代码可运行

新年伊始,终到百篇,龙年大吉。

题目1

题目链接 题目大意: 给出一个整数,问该整数能否切分为两个数字a和b,满足: 1、a和b都不包括前导零,是一个正常的数字; 2、a和b都大于0; 3、b > a;

如果可以,则输出数字a和b;如果不可以则输出-1;

输入: 第一行,整数𝑡 表示t个样例 𝑡 (1≤𝑡≤10000) 每个样例一行,单个整数 (数字长度为2~8)

输出: 每个样例一行,如果可以,则输出数字a和b;如果不可以则输出-1;

Examples input 5 20002001 391125 200200 2001000 12

output 2000 2001 39 1125 -1 200 1000 1 2

题目解析: 按照题目的要求,a要尽可能小,b要尽可能大。 由于题目给出的数字本身就合法,那么将第一个数字开始分为a,往后找到第一个非零的数字就分给b,这样b一定是最大的。 从字符串上切分好a和b,接下来就是转成数字。 这里为了便于计算,从字符串a右边开始往左边枚举每一个位置上的数字,就可以得到数字a。(数字b同理,也可以字符串切割后,用sscanf取巧)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
    static const int N = 201010;
public:
    void solve() {
        int t;
        cin >> t;
        while (t--) {
            string str;
            cin >> str;
            int k = 1, n = str.length();
            while (k < n) {
                if (str[k] != '0') break;
                ++k;
            }
            if (k >= n) {
                cout << -1 << endl;
                continue;;
            }
            int x = 0, y = 0;
            int tmp = k - 1, val = 1;
            while (tmp >= 0) {
                x += val * (str[tmp] - '0');
                --tmp;
                val *= 10;
            }
            tmp = n - 1, val = 1;
            while (tmp >= k) {
                y += val * (str[tmp] - '0');
                --tmp;
                val *= 10;
            }
            if (x < y) cout << x << " " << y << endl;
            else  cout << -1 << endl;
        }
    }
}
ac;

题目2

题目链接 题目大意: 给出一个01字符组成的字符串𝑠,现在可以对字符串进行任意次下面操作: 1、删除字符串中的某个一个字符,代价为1; 2、调换两个位置上的字符,代价为0;

现在要求,若干次操作后的字符串t,t上面每一个字符都与原来字符串s的字符相反,比如说: s=011 那么t=10,最小操作代价是1,移除一个字符1,然后交换一次0、1的位置;

s=111100 那么t=00,最小操作代价是4,移除所有字符1;

问生成满足要求的字符串t,最小的代价是多少。(注意移除所有字符也满足要求)

输入: 第一行,整数𝑡 表示t个样例 𝑡 (1≤𝑡≤10000) 每个样例一行,字符串𝑠 (1≤ |𝑠| ≤2⋅1e5)

输出: 每个样例一行,输出满足题目要求的最小代价;

Examples input 4 0 011 0101110001 111100

output 1 1 0 4

题目解析: 按照题目的要求,直接看最终字符串t的样式,比如说s=111100,那么t=001111; 那么只需要累计原来0、1的数字数量,然后从左到右枚举t的位置,直到剩下的字符无法填充,那么就得到t的最大长度; 得到t的最大长度k,那么需要移除的字符串长度就是n--k。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
    static const int N = 201010;
public:
    void solve() {
        int t;
        cin >> t;
        while (t--) {
            string str;
            cin >> str;
            int n = str.length(), x = 0, y = 0;
            for (int i = 0; i < n; ++i)
                if (str[i] == '0') ++x;
                else ++y;
            int k = 0, cntX = x, cntY = y;
            while (k < n) {
                if (str[k] == '0') {
                    if (y > 0) --y;
                    else break;
                }
                else {
                    if (x > 0) --x;
                    else break;
                }
                ++k;
            }
            if (x + y == 0) {
                cout << 0 << endl;
            }
            else {
                cout << n - k << endl;
            }
        }
    }
}
ac;

题目3

题目链接 题目大意: 给出一个空的数组,现在有两个操作: 操作1,往数组添加一个数字2^x; 操作2,询问数组中的若干个数字,数字和是否可以为w;

输入: 第一行,整数𝑡 表示m个操作 (1≤m≤100000) 每个操作一行 操作1,是输入1和x (0≤x≤29 ). 操作2,是输入2和w;(0≤w≤1e9 ).

输出: 每个操作2输出一行,存在则输出YES,不存在输出NO;

Examples input 5 1 0 1 0 1 0 2 3 2 4

output YES NO

题目解析: 题目的数据范围简化了题目,首先x比较小,数组中最多只有30个整数类型,那么可以按照这个规则聚类; 其次,在判断数组是否存在某个元素和时,可以从大到小遍历数组,对于某个元素y如果小于等于当前w,则优先取用,并且w=w-y,直到数组末尾;如果此时w=0,则有解,否则无解;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
   static const int M = 536870912; // 2^29
   int a[30];
public:
   void solve() {
       int t;
       cin >> t;
       while (t--) {
           int k, x;
           cin >> k >> x;
           if (k == 1) a[x]++;
           else {
               int cur = M;
               for (int i = 29; i >= 0; --i) {
                   if (a[i] > 0 && x >= cur) {
                       int left = 1, right = a[i] + 1;
                       int find = left;
                       while (left < right) {
                           int mid = (left + right) / 2;
                           lld sum = 1LL * mid * cur;
                           if (sum > x) {
                               right = mid;
                           }
                           else {
                               find = mid;
                               left = mid + 1;
                           }
                       }
                       x -= find * cur;
                   }
                   cur /= 2;
               }
               cout << (x == 0 ? "YES" : "NO") << endl;
           }
           
       }
   }
}
ac;

题目4

题目链接 题目大意: 有两个整数n和k,n表示字符串长度,k表示字符串由前k个小写字符; 现在需要构造一个字符串s,要求任何长度为n的字符串,都是字符串s的子序列;

输入: 第一行,整数𝑡 表示t个样例 𝑡 (1≤𝑡≤676) 每个样例一行,整数n和k (1≤𝑛≤26 ) and (1≤𝑘≤26 ).

输出: 每个样例一行,输出字符串s,如果有多个则输出最短长度的字符串;

Examples input 4 1 2 2 1 2 2 2 3

output ab aa baab abcbac

题目解析: 题目的要求,所有常读为n的字符串,在拼接的时候就可以看成是n个选择,每次从k个字符中选择一个; 那么在构造的时候,可以采用这样的策略: 我们重复abc/abc/abc这样的字符串,每一组都相当有k个不同字符的桶。 这样构造出来的结果就能满足要求。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
    static const int N = 201010;
public:
    void solve() {
        int t;
        cin >> t;
        while (t--) {
            int n, k;
            cin >> n >> k;
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < k; ++j) putchar('a' + j);
            }
            cout << endl;
        }
    }
}
ac;

题目5

题目链接 题目大意: 有一个正整数x,现在需要把x分成n个正整数,这些正整数之和是x; 现在要求,n个正整数的最大公约数,尽可能的大;

输入: 第一行,整数𝑡 表示t个样例 𝑡 (1≤𝑡≤1000) 每个样例一行,整数𝑥和 𝑛 (1≤𝑥≤1e8) and (1≤𝑛≤𝑥).

输出: 每个样例一行,输出最大的公约数。

Examples input 3 10 3 5 5 420 69

output 2 1 6

题目解析: 按照题目的要求,全部拆分成数字1,必然可以拆出满足要求: k-1个整数1,剩下的整数是x-n-1,这些整数的最大公约数是1;

同理,假如最大公约数是2,可以这么拆: k-1个整数2,剩下的整数是x-2n-2,最大的公约数是2;

也就是说,假设最大公约数是k,也可以这么安排:n-1个整数k,剩下是x-kn-k;

由于题目的范围不大,那么枚举最大公约数的数字就好。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
  static const int N = 201010;
public:
  void solve() {
      int t;
      cin >> t;
      while (t--) {
          int x, n;
          cin >> x >> n;
          int k = sqrt(x) + 1;
          int ans = 1;
          for (int i = 1; i <= k; ++i) {
              if (x % i == 0) {
                  if (i >= n) ans = max(ans, x / i);
                  if (x / i >= n) ans = max(ans, i);
              }
          }
          cout << ans << endl;
      }
  }
}
ac;
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-03-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
程序员进阶之算法练习(七十一)
题目链接 题目大意: 给出n个整数,每次可以选择其中两个整数a[i]和a[j],令a[i]=x和a[j]=y,但是需要满足a[i] | a[j] = x | y;(|是或操作) 现在可以进行任意次操作,问n个整数的最小和是多少。
落影
2023/01/01
2230
程序员进阶之算法练习(七十五)
题目链接 题目大意: 给出整数n、a、b,询问是否存在由数字1到n组成的排列p和q,满足下面条件: 排列p和q的最长公共前缀长度是a; 排列p和q的最长公共后缀长度是b;
落影
2023/03/12
2230
程序员进阶之算法练习(六十)
题目链接 题目大意: 给出一个整数n,求一个最大整数满足: 1、整数各个数字加起来等于n; 2、没有两个相同的数字相邻; 3、数字中不包括0;
落影
2022/04/24
2130
程序员进阶之算法练习(六十)
程序员进阶之算法练习(五十四)
题目链接 题目大意: 给出n个整数,还有一个数字d; 要求去除最少的数字,使得剩余数字的最大最小值差不大于d;
落影
2021/11/24
2600
程序员进阶之算法练习(五十四)
程序员进阶之算法练习(八十二)
题目链接 题目大意: 给出一个整数n,构造一个长度为n的整数数组a,满足: 1、1≤𝑎𝑖≤1000 对于所有的 1≤𝑖≤𝑛; 2、𝑎𝑖 能整除𝑖,对于所有的 1≤𝑖≤𝑛; 3、𝑎1+𝑎2+…+𝑎𝑛 能够整除 𝑛 .
落影
2023/08/13
2060
程序员进阶之算法练习(九十九)
题目链接 题目大意: 有三个长度为n的字符串a、b、c,字符串都是小写字符; 有一个长度为n的模版t,模版会与字符串a、b、c匹配,匹配规则如下: 1、假如模版的字符为小写字母,则对应位置必须是相同字符才算匹配; 2、假如模版的字符为大写字母,则对应位置则不能是相同字符才算匹配; 比如说模板abc和字符串abc是匹配的,模板ABC和字符串def也是匹配的,模板ABC和字符串abc是不匹配的;
落影
2024/02/25
1380
程序员进阶之算法练习(四十四)
正文 题目1 题目链接 题目大意: 给出整数x,求两个整数a和b,满足: ???(?,?)+???(?,?)=? . GCD是最大公约数; LCM是最小公约数; 题目保证a和b存在; 输入:
落影
2020/06/08
4430
程序员进阶之算法练习(四十四)
程序员进阶之算法练习(八十)
题目链接 题目大意: 有一个数组a,仅有整数1和-1组成,我们定义数组a的乘积为: 对于 1≤𝑖<𝑗≤𝑛, 𝑎[𝑖]⋅𝑎[𝑗]=1的数量。
落影
2023/07/25
1930
程序员进阶之算法练习(七十七)
题目链接 题目大意: 给出n个整数的数组a,数组的元素可能是1或者2; 现在想要找到一个最小的位置k满足: 𝑎1⋅𝑎2⋅…⋅𝑎𝑘=𝑎𝑘+1⋅𝑎𝑘+2⋅…⋅𝑎𝑛
落影
2023/05/27
2070
程序员进阶之算法练习(七十九)
题目链接 题目大意: 有n个人参加投票,小明是第一个; 投票一共k轮,每轮每个人会做出一个选择,分别用+和-表示,那么一共有三个结果: +的人数大于-的人数,那么-的人出局; -的人数大于+的人数,那么+的人出局; 如果+和-的人数一样多,那么所有人出局; 出局的人,不再参与后续投票。
落影
2023/07/09
1560
程序员进阶之算法练习(八十一)
题目链接 题目大意: 给出n个整数的数组,现在可以对数组进行以下操作: 选择数组中任意两个不同的整数a[i]和a[j],令a[i]=x,a[j]=y,其中满足x*y = a[i] * a[j];
落影
2023/08/09
3530
程序员进阶之算法练习(七十四)
题目链接 题目大意: 给出一个整数n,现在可以对整数执行一个操作: 选择整数上两个不同位数的数字交换位置,然后移除整数最右边一位的数字; 重复这个过程,直到整数只剩下1位; 现在想知道这个剩下的数字最小可能为多少。
落影
2023/03/07
2060
程序员进阶之算法练习(九十五)
题目链接 题目大意: 有n个整数的数组a,现在需要构造一个1到n的排列b; 令𝑐𝑖 = 𝑎𝑖−𝑏𝑖,希望最终𝑐𝑖 出现尽可能多的不同整数。
落影
2024/01/06
1290
程序员进阶之算法练习(九十五)
程序员进阶之算法练习(七十)
题目链接 题目大意: 给出一个数组长度为n,每次可以选择若干个数字,将其数字+1; 问最少需要操作几次,才能让整个数组内的元素值相等。
落影
2022/12/18
5560
程序员进阶之算法练习(九十七)
现在光标停留在最左边的数字1处,我们可以进行以下的操作: 1、将当前光标所在位置的数字输出; 2、移动光标到相邻的数字,比如说从1移动到2,从2移动到3;(1的左边不能移动,0的右边不能移动)
落影
2024/02/10
1130
程序员进阶之算法练习(九十七)
程序员进阶之算法练习(九十三)
题目链接 题目大意: 有3个字符a/b/c,排成一行; 现在可以选择两个字符,交换对应的位置; 上述操作最多只能执行一次,问能否得到abc的顺序。
落影
2023/12/18
1490
程序员进阶之算法练习(七十三)
题目链接 题目大意: 有两种车分别有4个轮子和6个轮子,现在只知道若干个车的轮子总数,想知道最少和最多有几辆车;
落影
2023/03/07
3010
程序员进阶之算法练习(九十四)
题目链接 题目大意: 有n个整数组成的数组a,现在可以对数组a的元素任意打乱顺序,要求满足: 假设打乱后的数组是b,要满足:𝑏1+𝑏2=𝑏2+𝑏3=…=𝑏𝑛−1+𝑏𝑛=k 也就是相邻两个数字的和相同。
落影
2023/12/23
1050
程序员进阶之算法练习(九十四)
程序员进阶之算法练习(六十一)
题目链接 题目大意: 给出正整数n,求整数1到整数n之中,有多少整数是由单一的字符组成,比如说1 , 77, 777, 44 和 999999 就是符合要求的整数。 整数1到18中,只有 1, 2, 3, 4, 5, 6, 7, 8, 9 和 11符合要求。
落影
2022/05/13
2150
程序员进阶之算法练习(七十二)
题目链接 题目大意: 给出一个字符串,由小写字母组成; 现在Alice和Bob在玩游戏,轮流从字符串中移除一个子串,Alice先操作; Alice允许移除偶数长度子串,Bob允许移除奇数长度子串;(也允许不移除) 最终看每个人移除子串的分数总和,字母a是1分,b是2分、、、z是26分; 问最终谁能赢得游戏,以及胜者领先的分数;
落影
2023/03/07
2680
推荐阅读
相关推荐
程序员进阶之算法练习(七十一)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验