2022-3-3

 双向排序

题目描述

给定序列 (a1​,a2​,⋅⋅⋅,an​)=(1,2,⋅⋅⋅,n),即 ai​=i。

小蓝将对这个序列进行 m 次操作,每次可能是将 a1​,a2​,⋯,aqi​​ 降序排列,或者将 aqi​​,aqi+1​​,⋯,an​ 升序排列。

请求出操作完成后的序列。

输入描述

输入的第一行包含两个整数 n,m​,分别表示序列的长度操作次数

接下来 m​ 行描述对序列的操作,其中第 i 行包含两个整数 pi​,qi​​ 表示操作类型参数。当 pi​=0​​ 时,表示将 a1​,a2​,⋅⋅⋅,aqi​​​​ 降序排列;当 pi​=1​ 时,表示将 aqi​​,aqi+1​​,⋯,an​​ 升序排列。

输出描述

输出一行,包含 n 个整数,相邻的整数之间使用一个空格分隔,表示操作完成后的序列。

输入

3 3
0 3
1 2
0 2

输出

3 1 2

样例说明

原数列为 (1, 2, 3)​​​​​。

第 1 步后为 (3, 2, 1)​​​​​。

第 2 步后为 (3, 1, 2)​​。

第 3​​​ 步后为 (3, 1, 2)​。与第 2 步操作后相同,因为前两个数已经是降序了。

评测用例规模与约定

对于 30% 的评测用例,n,m≤1000;用最快的排序:mlog2n(可以),下面规模就不可以了,能拿30%的分已经不错了,我感觉。

对于 60% 的评测用例,n,m≤5000;

对于所有评测用例,1≤n,m≤100000,0≤pi​≤1,1≤qi​≤n。

 如果是考试,我就会这么写,因为估计最后也没时间想怎么优化了。

#include<iostream>
using namespace std;

//双向排序
#include<algorithm>
bool cmp(int a,int b){//降序,sort默认升序
    return a>b;
}
int main()
{
    int n,m,p,q,a[1001];
    cin>>n>>m;//序列长度和操作次数
    for(int i=1;i<=n;i++)
      a[i]=i;//序列从1开始,a0不用
    for(int i=1;i<=m;i++){
        cin>>p>>q;//操作类型和参数
        if(p==0){
            sort(a+1,a+q+1,cmp);//a代表从a0开始排,所以最后一个数的位置需要+1
        }else {
            sort(a+q[i],a+n+1);
        } 
    }
    for(int i=1;i<=n;i++)
      cout<<a[i]<<" ";
    return 0;
}

对60%: 

//对60%的测试用例
#include<iostream>
using namespace std;
#include<cstring>
int main()
{
    int n,m,p,q,a[5001],flag[5001];
    int i,j,k;
    cin>>n>>m;//序列长度和操作次数
    for(i=1;i<=n;i++)
      a[i]=i;//序列从1开始,a0不用
    for(i=1;i<=m;i++){
        cin>>p>>q;//操作类型和参数
        memset(flag,0,sizeof(flag));
        if(p==0){//降序排列
          for(j=1;j<=q;j++)
            flag[a[j]]=1;//将这个数标记为1
          k=1;//将标记为1个数重新插入到数组的第k个位置
          for(j=n;j>=1;j--){//从后向前(因为a中的数升序排列)
            if(flag[j]==1){
                a[k++]=j;
            }
          }
        } 
        else{//升序排列
           for(j=q;j<=n;j++)
             flag[a[j]]=1;
           k=q;
           for(j=1;j<=n;j++){//从前向后插入
             if(flag[j]==1){
               a[k++]=j;
             }
           }
        }
    }
    for(i=1;i<=n;i++)
      cout<<a[i]<<" ";
    return 0;
}

对100%

 明码

题目描述

汉字的字形存在于字库中,即便在今天,16 点阵的字库也仍然使用广泛。

16 点阵的字库把每个汉字看成是 16×16 个像素信息。并把这些信息记录在字节中。

一个字节可以存储 8 位信息,用 32 个字节就可以存一个汉字的字形了。 把每个字节转为 2 进制表示,1 表示墨迹,0 表示底色。每行 2 个字节,一共 16 行,布局是:

    第 1 字节,第 2 字节
    第 3 字节,第 4 字节
    ....
    第 31 字节, 第 32 字节

这道题目是给你一段多个汉字组成的信息,每个汉字用 32 个字节表示,这里给出了字节作为有符号整数的值。

题目的要求隐藏在这些信息中。你的任务是复原这些汉字的字形,从中看出题目的要求,并根据要求填写答案。

这段信息是(一共 10 个汉字):

4 0 4 0 4 0 4 32 -1 -16 4 32 4 32 4 32 4 32 4 32 8 32 8 32 16 34 16 34 32 30 -64 0 
16 64 16 64 34 68 127 126 66 -124 67 4 66 4 66 -124 126 100 66 36 66 4 66 4 66 4 126 4 66 40 0 16 
4 0 4 0 4 0 4 32 -1 -16 4 32 4 32 4 32 4 32 4 32 8 32 8 32 16 34 16 34 32 30 -64 0 
0 -128 64 -128 48 -128 17 8 1 -4 2 8 8 80 16 64 32 64 -32 64 32 -96 32 -96 33 16 34 8 36 14 40 4 
4 0 3 0 1 0 0 4 -1 -2 4 0 4 16 7 -8 4 16 4 16 4 16 8 16 8 16 16 16 32 -96 64 64 
16 64 20 72 62 -4 73 32 5 16 1 0 63 -8 1 0 -1 -2 0 64 0 80 63 -8 8 64 4 64 1 64 0 -128 
0 16 63 -8 1 0 1 0 1 0 1 4 -1 -2 1 0 1 0 1 0 1 0 1 0 1 0 1 0 5 0 2 0 
2 0 2 0 7 -16 8 32 24 64 37 -128 2 -128 12 -128 113 -4 2 8 12 16 18 32 33 -64 1 0 14 0 112 0 
1 0 1 0 1 0 9 32 9 16 17 12 17 4 33 16 65 16 1 32 1 64 0 -128 1 0 2 0 12 0 112 0 
0 0 0 0 7 -16 24 24 48 12 56 12 0 56 0 -32 0 -64 0 -128 0 0 0 0 1 -128 3 -64 1 -128 0 0 
#include<iostream>
using namespace std;

//明码
#include<bitset>
#include<cmath>
int main()
{
  int n,m;
  string s1,s2;
  while(cin>>n>>m){
    bitset<8> b(n);
    s1=b.to_string();
    for(int i=0;i<s1.length();i++){
      if(s1[i]=='0') cout<<" ";
      else cout<<"*";
    }
    bitset<8> c(m);
    s2=c.to_string();
    for(int i=0;i<s2.length();i++){
      if(s2[i]=='0') cout<<" ";
      else cout<<"*";
    }
    cout<<endl;
  }
    // long long ans=pow(9,9);//一定要用long long存再输出!!!
    // cout<<ans<<endl;
    return 0;
}
//  每次输入两个整型数(一个整型数代表一个字节。符合题意),直到文本结束
//  bitset<8> b(n);//类似数组结构,大小8位,只能存放0和1,一个元素占1位。 bitset<大小> 结构名(所需处理的整形数或字符串)
//  to_string 函数:将数字常量转换为字符串,返回值为转换完毕的字符串

 运行后得到:九的九次方等于多少?

星期一

题目描述

整个 2020 世纪(1901 年 1 月 1 日至 2000 年 12 月 31 日之间),一共有多少个星期一?(不要告诉我你不知道今天是星期几)

注意点:判断数字是否合法是,month容易忽略不能<1,day不能=0

第几天

2000 年的 1 月 1 日,是那一年的第 1 天。

那么,2000 年的 5 月 4 日,是那一年的第几天?

#include<iostream>
using namespace std;

//星期一
bool isLeap(int y){//判断闰年
    return (y%4==0&&y%100!=0)||(y%400==0);
}
bool check(int i){//判断日期是否合法
    int year,month,day;
    int m[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    year=i/10000;
    month=i/100%100;
    day=i%100;
    if(year>2000) return false;
    else{
        if(month>12||month<1) return false;
        else{
          if(isLeap(year)) m[2]=29;
          else m[2]=28;
          if(day>m[month]||day==0) return false;
        }
    }
    return true;
}
int main()
{
    int ans=0,xq=0,sum=0;//sum记录几个合法i了,不可与星期混用!!!
    for(int i=19010101;i<=20001231;i++){//1901/01/01:星期2(看电脑上的日历)
        if(check(i)){
            xq=(sum+2)%7;
            if(xq==1) ans++;
            sum++;
        }
    }
    cout<<ans<<endl;
    return 0;
}

第几天(main函数只留sum,i的范围一改即可) 这题同理 星期一

乘积尾零

题目描述

如下的 10 行数据,每行有 10 个整数,请你求出它们的乘积的末尾有多少个零

5650 4542 3554 473 946 4114 3871 9073 90 4329 
2758 7949 6113 5659 5245 7432 3051 4434 6704 3594 
9937 1173 6866 3397 4759 7557 3070 2287 1453 9899 
1486 5722 3135 1170 4014 5510 5120 729 2880 9019 
2049 698 4582 4346 4427 646 9742 7340 1230 7683 
5693 7015 6887 7381 4172 4341 2909 2027 7355 5649 
6701 6645 1671 5978 2704 9926 295 3125 3878 6785 
2066 4247 4800 1578 6652 4616 1113 6205 3264 2915 
3966 5291 2904 1285 2193 1428 2265 8730 9436 7074 
689 5510 8243 6114 337 4096 8199 7313 3685 211 

 2的倍数与5相乘都会产生一个零,因此要找每个数的因子含几对2和5

#include<iostream>
using namespace std;

//乘积尾零
int main()
{
    int a[100],cnt2=0,cnt5=0;
    for(int i=0;i<100;i++){
        cin>>a[i];
        while(a[i]%2==0){
            cnt2++;
            a[i]/=2;
        }
        while(a[i]%5==0){
            cnt5++;
            a[i]/=5;
        }
    }
    cout<<min(cnt2,cnt5)<<endl;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值