5 条题解

  • 2
    @ 2022-8-9 22:07:02

    给一个稍微简单的思路,就是首先找到数组中不符合升序的首尾,将这段元素颠倒后核对。

    #include <bits/stdc++.h>
    using namespace std;
    int t, n, sum;
    int a[1005];
    int main()
    {
        cin >> t;
        for (int i = 1; i <= t; i++)
        {
            cin >> n;
            for (int i = 1; i <= n; i++)
                cin >> a[i];
            int l = 0, r = 0;
            for (int i = 1; i < n; i++)
            { //从前往后判断,如果前一项大于后一项说明后面的要开始反转
                if (a[i] > a[i + 1])
                {
                    l = i;
                    break;
                }
            }
            for (int i = n; i >= 1; i--)
            { //从后往前判断,如果前一项大于后一项说明要翻转
                if (a[i] < a[i - 1])
                {
                    r = i;
                    break;
                }
            }
            reverse(a + l, a + r + 1);//把这一段进行翻转
            bool flag = true;//定义布尔变量保存是否能够翻转得到
            //检验翻转后数组是否为升序
            for (int i = 1; i < n; i++)
            {
                if (a[i + 1] < a[i])
                {
                    flag = false;
                    //出现不符合升序直接结束循环
                    break;
                }
            }
            if (flag)
                cout << "yes" << endl;
            else
                cout << "no" << endl;
        }
        return 0;
    }
    
    • 1
      @ 2022-8-8 22:32:41

      首发算是了QwQ

      #include<bits/stdc++.h>
      using namespace std;
      const int maxn=1e9+5;
      /* l和r数组用来记录每组翻转的起点和终点 */
      short t,n,l[1001],r[1001];
      int cnt; // 用来记录是第几组翻转
      int main(){
          ios::sync_with_stdio(false);
          cin.tie(0);
          cout.tie(0);
          cin>>t;
          for(short i=1;i<=t;i++){
              cin>>n;
              l[cnt=1]=1;
              r[1]=1;
              bool flag=true; // 遇到降序排列,可以记录进l、r数组
              int a[1001];
              for(short j=1;j<=n;j++){
                  cin>>a[j];
              }
              for(short j=1;j<n;j++){
                  if(a[j]>a[j+1]){ // 如果是降序
                      r[cnt]=j+1; // 把翻转终点设置成数组降序排列的终点
                      flag=true; // 遇到降序排列,可以记录进l、r数组
                  }else{
                      if(flag){ // 降序结束,进入升序
                          for(short k=j+1;k<=n;k++){
                              if(a[k]>a[k+1]){ // 如果后面有降序排列才会设置下一组翻转的起点
                              // 就是说升序结尾才会设置,避免遗漏
      
                                  l[++cnt]=k; // 进入下一组的设置
                                  flag=false;
                                  break; // 防止重复设置
                              }
                          }
                      }
                  }
              }
              if(flag){ // 结尾可能出现遗留未设置成最后一组的结尾
                  if(a[n-1]>a[n])r[cnt]=n; // 只有结尾两个数字是降序时才会发生遗留问题
              }else{
                  cnt--; // 如果数组结尾设置了下一组的起始但是没有设置结尾就要把最后一组设置成上一组
              }
              flag = true; // 默认输出no(同样的变量换一个用处(懒得设置新变量了))
              for(short j=1;j<=cnt;j++){ // 遍历所有翻转组
                  reverse(a+l[j],a+r[j]+1); // 翻转原数组
                  bool flag2 = true; // 默认输出yes
                  for(short k=1;k<n;k++){ // 检测翻转后是否为单调升序
                      if(a[k]>=a[k+1]){ // 如果出现降序情况
                          flag2 = false; // 不输出yes(也不输出no,进入下个循环遍历)
                          break;
                      }
                  }
                  if(flag2){
                      cout<<"yes\n";
                      flag = false; // 不输出no(输出yes)
                      reverse(a+l[j],a+r[j]+1); // 把翻转后的数组翻转回原数组,下次还要用
                      break; // 注意这个break会把循环跳到外面,不会执行下面的reverse
                  }
                  reverse(a+l[j],a+r[j]+1); // 把翻转后的数组翻转回原数组,下次还要用
              }
              if(flag)cout<<"no\n"; // 输出no
              // 输入下一组数据
          }
          return 0;
      }
      
    • 0
      @ 2024-3-13 16:57:20
      '''
      大体思路:
      1.拿到数据包;
      2.拆解每组数据并依次对比翻转逻辑;
      3.每次判定完成后,统一录入待输出列表等待输出
      '''
      res = []       # 待输出的空列表,用来统计yes和no
      def print_res(res):
          # 将结果依次输出
          for z in res:
              print(z)
      def f(r):
          # 设置映射的规则
          return int(r)
      def pickNum_1(s1,s2):
          # 判断每组数据是否符合翻转逻辑,并将结果存储res列表
          s_l = len(s1)                         # 数组长度
          if s1 == s2:                          # 假如数组单调递减,一定符合
              res.append("yes")
          else:                                 # 思路1:根据升序结果,对比并截取被“翻转”过的一整段数组
              for j in range(s_l):                # 从左边数第一个不同是起点索引
                  if s1[j] > s2[j]:
                      l_ = j
                      break
              for h in range(s_l-1,0,-1):         # 从右边数第一个不同是终点索引
                  if s1[h] < s2[h]:
                      r_ = h + 1
                      break
              r_list_1 = s1[l_:r_]                # 根据索引段,截取原始数组
              r_list_2 = s2[l_:r_]                # 根据索引段,截取升序数组
              if r_list_1 == r_list_2[::-1]:    # 思路2:如果截取的数组本身符合“镜像”的逻辑,那原数组就符合翻转逻辑
                  res.append("yes")
              else:
                  res.append("no")
      
      def getNumList():
          t = int(input())                     # 数据包中数组组数
          for i in range(t):
              n = int(input())
              s_ = list(input().split())       # 获取依次输入的数字,并整理至列表
              s1 = list(map(f,s_))             # 以设定好的规则,映射出一个原始的整数列表
              s2 = sorted(s1)                  # copy一个升序列表
              pickNum_1(s1, s2)                # 对每个数组判定是否符合“翻转”逻辑
          print_res(res)
      getNumList()
      
      '----------------------人生苦短,我用Python *^__^*----------------------'
      
      
      • 0
        @ 2023-4-18 20:03:21

        `#include<bits/stdc++.h> using namespace std; const int maxn=1e9+5; /* l和r数组用来记录每组翻转的起点和终点 */ short t,n,l[1001],r[1001]; int cnt; // 用来记录是第几组翻转 int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>t; for(short i=1;i<=t;i++){ cin>>n; l[cnt=1]=1; r[1]=1; bool flag=true; // 遇到降序排列,可以记录进l、r数组 int a[1001]; for(short j=1;j<=n;j++){ cin>>a[j]; } for(short j=1;j<n;j++){ if(a[j]>a[j+1]){ // 如果是降序 r[cnt]=j+1; // 把翻转终点设置成数组降序排列的终点 flag=true; // 遇到降序排列,可以记录进l、r数组 }else{ if(flag){ // 降序结束,进入升序 for(short k=j+1;k<=n;k++){ if(a[k]>a[k+1]){ // 如果后面有降序排列才会设置下一组翻转的起点 // 就是说升序结尾才会设置,避免遗漏

        l[++cnt]=k; // 进入下一组的设置
                                flag=false;
                                break; // 防止重复设置
                            }
                        }
                    }
                }
            }
            if(flag){ // 结尾可能出现遗留未设置成最后一组的结尾
                if(a[n-1]>a[n])r[cnt]=n; // 只有结尾两个数字是降序时才会发生遗留问题
            }else{
                cnt--; // 如果数组结尾设置了下一组的起始但是没有设置结尾就要把最后一组设置成上一组
            }
            flag = true; // 默认输出no(同样的变量换一个用处(懒得设置新变量了))
            for(short j=1;j<=cnt;j++){ // 遍历所有翻转组
                reverse(a+l[j],a+r[j]+1); // 翻转原数组
                bool flag2 = true; // 默认输出yes
                for(short k=1;k<n;k++){ // 检测翻转后是否为单调升序
                    if(a[k]>=a[k+1]){ // 如果出现降序情况
                        flag2 = false; // 不输出yes(也不输出no,进入下个循环遍历)
                        break;
                    }
                }
                if(flag2){
                    cout<<"yes\n";
                    flag = false; // 不输出no(输出yes)
                    reverse(a+l[j],a+r[j]+1); // 把翻转后的数组翻转回原数组,下次还要用
                    break; // 注意这个break会把循环跳到外面,不会执行下面的reverse
                }
                reverse(a+l[j],a+r[j]+1); // 把翻转后的数组翻转回原数组,下次还要用
            }
            if(flag)cout<<"no\n"; // 输出no
            // 输入下一组数据
        }
        return 0;
        

        }

        using namespace std;
        const int maxn=1e9+5;
        /* l和r数组用来记录每组翻转的起点和终点 */
        short t,n,l[1001],r[1001];
        int cnt; // 用来记录是第几组翻转
        int main(){
            ios::sync_with_stdio(false);
            cin.tie(0);
            cout.tie(0);
            cin>>t;
            for(short i=1;i<=t;i++){
                cin>>n;
                l[cnt=1]=1;
                r[1]=1;
                bool flag=true; // 遇到降序排列,可以记录进l、r数组
                int a[1001];
                for(short j=1;j<=n;j++){
                    cin>>a[j];
                }
                for(short j=1;j<n;j++){
                    if(a[j]>a[j+1]){ // 如果是降序
                        r[cnt]=j+1; // 把翻转终点设置成数组降序排列的终点
                        flag=true; // 遇到降序排列,可以记录进l、r数组
                    }else{
                        if(flag){ // 降序结束,进入升序
                            for(short k=j+1;k<=n;k++){
                                if(a[k]>a[k+1]){ // 如果后面有降序排列才会设置下一组翻转的起点
                                // 就是说升序结尾才会设置,避免遗漏
        
                                    l[++cnt]=k; // 进入下一组的设置
                                    flag=false;
                                    break; // 防止重复设置
                                }
                            }
                        }
                    }
                }
                if(flag){ // 结尾可能出现遗留未设置成最后一组的结尾
                    if(a[n-1]>a[n])r[cnt]=n; // 只有结尾两个数字是降序时才会发生遗留问题
                }else{
                    cnt--; // 如果数组结尾设置了下一组的起始但是没有设置结尾就要把最后一组设置成上一组
                }
                flag = true; // 默认输出no(同样的变量换一个用处(懒得设置新变量了))
                for(short j=1;j<=cnt;j++){ // 遍历所有翻转组
                    reverse(a+l[j],a+r[j]+1); // 翻转原数组
                    bool flag2 = true; // 默认输出yes
                    for(short k=1;k<n;k++){ // 检测翻转后是否为单调升序
                        if(a[k]>=a[k+1]){ // 如果出现降序情况
                            flag2 = false; // 不输出yes(也不输出no,进入下个循环遍历)
                            break;
                        }
                    }
                    if(flag2){
                        cout<<"yes\n";
                        flag = false; // 不输出no(输出yes)
                        reverse(a+l[j],a+r[j]+1); // 把翻转后的数组翻转回原数组,下次还要用
                        break; // 注意这个break会把循环跳到外面,不会执行下面的reverse
                    }
                    reverse(a+l[j],a+r[j]+1); // 把翻转后的数组翻转回原数组,下次还要用
                }
                if(flag)cout<<"no\n"; // 输出no
                // 输入下一组数据
            }
            return 0;
        }
        `
        
        • -4
          @ 2022-4-24 16:43:26

          写题解请注意

          鼓励大家写题解,但注意题解格式。

          题解一定要有思路解析或代码注释,能否让别人理解你的思路

          也是你的能力的检验,不要只放无意义的代码给大家复制,那就失去了做题的初心。

          给代码两端加上这个会舒服一些

          ```cpp

          你的代码

          ```

          </span>

          这个点在键盘的左上角tab上面那个键,注意切换输入法

          #include<iostream>
          using namespace std;
          int main()
          {
              int n;
              cin>>n;//这是一个注释
              return 0;
          } 
          

          请注意严禁抄袭题解,写题解不要只放代码,需加上你的思路或代码注释。

          抄袭题解一经发现直接取消成绩。

          题解被删除的可能

          1. 代码不符合格式规范
          2. 没有思路讲解或者没有注释,
          3. 无意义的题解

          大家携手共同维护一个良好的编程环境,如果一经发现,多次作乱。可能会被管理员拉黑,请注意,一旦拉黑即失去登陆资格。

          • 1

          信息

          ID
          1238
          时间
          1000ms
          内存
          256MiB
          难度
          4
          标签
          递交数
          230
          已通过
          105
          上传者