【问题标题】:Generate String equals to given sum within given character生成字符串等于给定字符内的给定总和
【发布时间】:2018-03-14 17:45:59
【问题描述】:

给定两个数字 n 和 k,找到一个由小写字母组成的字符串 s,使得字符串中所有元素的值之和等于 k。 如果存在很多这样的字符串,则找出按字典顺序最小的那个。

第i个小写字母的值为i,例如a的值为1,b的值为2,以此类推。

输入格式: 输入的第一行包含一个整数 t,表示测试用例的数量。 后面有 t 行,每行包含两个以空格分隔的整数 n 和 k。

输出格式: 打印长度为 n 且字符串总和值等于 k ​​的字典序最小字符串。

约束:

1

1

n

示例输入:

2

5 42

3 25

样本输出:

aaamz

解释:

aaamz 的字符串值也是 42,它是最小的字典字符串,它包含 5 个字符,字符串值是 42。

【问题讨论】:

  • 这似乎是一个家庭作业问题,请求家庭作业帮助的问题必须包括迄今为止为解决该问题所做的工作摘要,以及您在解决该问题时遇到的困难的描述。
  • @irs102info 是否可能存在任何无效结果,例如像这样的情况 - 1 40 其中 n=1 和 k=40,这样的情况会存在吗?
  • 你有问题描述的链接吗,好像是网上发布的?
  • @zenwraight,是的,我们可以得到无效的结果,在这种情况下我们必须打印'-1'。我没有那个问题的链接。
  • @LakshayGarg,这是我解决问题的方法,char[] a = new char[n]; for(int i=0;i<n;i++){ a[i] = 'a'; } int a_count = n; int tot_count = k; int x = tot_count - a_count; for(int i=n-1;i>=0; i--){ if(x> 26){ a[i] = 'z'; x = (x-26)+1; } else if(x > 0){ a[i] = (char) (a[i] + x); x = 0; } if(x == 0) break; } String op=""; for(int i=0;i<n;i++){ op = op+a[i]; } System.out.println(op); 但我收到了 Time Limit Exceeds (TLE) 错误。有没有其他想法或方法可以更快地解决?

标签: arrays string algorithm data-structures


【解决方案1】:
generateLexicoString(int n, int k){
char[] a = new char[n];
    // Initially fill the array with character 'a'
    for(int i=0;i<n;i++){
        a[i] = 'a'; 
    }
    int a_count = n;
    int tot_count = k;
    int x = tot_count - a_count;
    for(int i=n-1;i>=0; i--){
        if(x> 26){
            a[i] = 'z';
            x = (x-26)+1;
        }
        else if(x > 0){
            a[i] = (char) (a[i] + x);
            x = 0;
        }
        if(x == 0)
            break;
    }
    String op="";
    for(int i=0;i<n;i++){
        op = op+a[i];
    }
    System.out.println(op);
}

【讨论】:

  • 这个程序似乎是 O(n),它不应该给你 TLE,嗯,很奇怪,因为我不认为你能做比这更好的事情。
  • 所以你得到了 TLE,这意味着你在某个地方在线提交这个代码到一个问题你可以发送链接到那个提交或问题吗?
  • @zenwraight 是的,这是我们公司作为编程实践的一部分主办的比赛,根据政策,链接不能与外界共享。
  • 您正在将字符附加到循环内的字符串。这需要为每个追加复制整个字符串,因此是 O(n^2) 操作。您可以尝试使用 stringstream 或在返回之前将其转换为 std::string 的 char 数组,这将使其成为 O(n) 操作。
【解决方案2】:

您可以使用 "System.out.print(a[i]);" 来避免字符串追加如下。

for(int i=0;i<n;i++){ System.out.print(a[i]); }

【讨论】:

    【解决方案3】:

    对不起,但我认为这里接受的解决方案缺少一个案例:

    如果 n = 2,k=28。 那么解决方案应该是“bz”。

     generateLexicoString(int n, int k){
    char[] a = new char[n];
        // Initially fill the array with character 'a'
        for(int i=0;i<n;i++){
            a[i] = 'a'; 
        }
        int a_count = n;
        int tot_count = k;
        int x = tot_count - a_count;
        for(int i=n-1;i>=0; i--){
            if(x> 26){
                a[i] = 'z';
                x = (x-26)+1;
            }
            else if(x == 26){
                a[i] = (char) (a[i] + 25);
                x = 1;
            }
            else if(x > 0){
                a[i] = (char) (a[i] + x);
                x = 0;
            }
            if(x == 0)
                break;
        }
    

    字符数组 a 将是我们的答案。

    【讨论】:

      【解决方案4】:

      在上面提供的解决方案中,它错过了 x 正好为 26 的情况。(这将失败,例如,n = 2 和 k = 28)。 因此,需要进行一些修改。

      generateLexicoString(int n, int k){
          char[] a = new char[n];
          // Initially fill the array with character 'a'
          for(int i=0;i<n;i++){
              a[i] = 'a'; 
          }
          int a_count = n;
          int tot_count = k;
          int x = tot_count - a_count;
          for(int i=n-1;i>=0; i--){
              if(x> 26){
                  a[i] = 'z';
                  x = (x-26)+1;
              }
              else if(x == 26){
               a[i] = (char) (a[i] + 25);
                x = x - 25; 
              }
              else if(x > 0){
                  a[i] = (char) (a[i] + x);
                  x = 0;
              }
              if(x == 0)
                  break;
          }
          String op= String.valueOf(a);
          System.out.println(op);
          // return op;
      }
      

      【讨论】:

        【解决方案5】:
        #include<bits/stdc++.h>
        using namespace std;
        
        int main() 
        {
            int t;
            cin>>t;
        
            while(t--)
            {
                int n,k;
                cin>>n>>k;
        
                string s="";
        
                for(int i=n;i>0;i--)
                {
                    if(k - (i-1) > 26)
                    {
                        s = 'z' + s;
                        k-=26;
                    }
                    else
                    {
                        char c = 'a' - 1 + k - (i-1);
                        s =  c + s;
                        k=i-1;
                    }
                }
        
                cout<<s<<endl;
            }
            return 0;
        }
        

        【讨论】:

          【解决方案6】:
               char arr[] = new char[n];
          
                  for (int i = n - 1; i >= 0; i--) {
          
                     if(k>0){
                         if(k>26){
                             k = k-26;
                             arr[i] = 'z';
                         }else{
                             int temp = k-i;
                             arr[i] = (char)(temp + 97 - 1);
                             k -= temp;
                         }
                     }else{
                         break;
                     }
                  }
          
                  return String.valueOf(arr);
          

          【讨论】:

          • 最好附上解释和理由,而不是只贴一段代码。
          猜你喜欢
          • 2021-02-02
          • 1970-01-01
          • 2016-10-30
          • 1970-01-01
          • 1970-01-01
          • 2012-02-13
          • 2011-02-03
          • 1970-01-01
          相关资源
          最近更新 更多