文章目录

  • A:会写脚本的月月鸟
  • B:别看了 这是水题
  • C:ACM脱单大法
  • D:Love_Jacques学长的游戏思维
  • E:后缀自动机next指针dag图上跑SG函数
  • F:新建 Microsoft PowerPoint 演示文稿.pptx
  • G:禁止复读
  • H:吓得我赶紧出了个签到题

A:会写脚本的月月鸟

解法1:

首先读了一下题目,嗷,水题,很快啊很快,有的同学啪的一下就来了一个暴力。然后就TLE了。
仔细分析一下这个序列长度 2∗1052*10^52∗105,在看询问的次数1∗1051*10^51∗105,如果每次询问都是1-n,这样时间复杂度是不是O(n∗m)=2∗1010O(n*m)=2*10^{10}O(n∗m)=2∗1010 ,看起来不可行。

所以我们想个办法来优化一下算法,每次询问区间[l−r][l-r][l−r]所有值得 与 运算。
这个与在二进制中有什么特性吗?
两个位都为1时,结果才为1
例如:10001&10100=10000

我们这样思考,如果把每个数看成由二进制组成得,每个数都小于1e9,也就是说对应得二进制位数最多只有31位,嗷,也就是说这个这个数就可以当成这个二进制每位对应十进制的大小之和。
比如说:110101对应的十进制大小就是
1∗20+0∗21+1∗22+0∗23+1∗24+1∗251*2^0+0*2^1+1*2^2+0*2^3+1*2^4+1*2^51∗20+0∗21+1∗22+0∗23+1∗24+1∗25

我们可以把这整个区间的每个数拆分成31份,对每位分别进行&运算后,最后把这31份的结果相加即可,那么问题就转换成如何快速的求出每一份的值是多少?
通过与运算我们可以知,假设这段区间每个数二进制的最低位 进行&运算,如果这段区间任意一个数二进制的最低位是0,那么算出来的最低位&的值即为0.

当我们分成31份进行计算时,对于二进制的某一位,序列是否出现过0,如果出现过0,则计算后这一位的结果是0。

到这里,题目就变成,对于某个区间,查询0的个数了。只不过要查找31次(因为有31位)。

O(1)时间复杂度查询的话,我们可以使用前缀和进行计算。

复杂度分析:
时间复杂度:O(31∗(n+m))O(31*(n+m))O(31∗(n+m))
空间复杂度:O(31∗n)O(31*n)O(31∗n)

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include<stdio.h>
#include<math.h>
#include<string.h>
const int maxn =2e5+10;
typedef long long ll;int dp[maxn][35];
int main(){int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){int x;scanf("%d",&x);for(int j=0;j<31;j++){if(((x>>j)&1)==0) dp[i][j]=dp[i-1][j]+1;else dp[i][j]=dp[i-1][j];   //前缀预处理0的个数}}for(int i=0;i<m;i++){int x,y;scanf("%d%d",&x,&y);int ans=0;for(int j=0;j<31;j++){if(dp[y][j]-dp[x-1][j]==0)  //如果等于0,代表这段区间这一位没有0出现ans+=(1<<j);}printf("%d\n",ans);}return 0;
}

解法2:

线段树,树状数组暴力莽一波。(建议先学会简单解法)
不过多介绍了,有兴趣的同学可以了解一下。
在建树后,它可以让单次查询的复杂度降为O(logn)O(logn)O(logn)

复杂度分析:
时间复杂度:O(n+m∗logn))O(n+m*logn))O(n+m∗logn))
空间复杂度:O(4∗n)O(4*n)O(4∗n)

线段树代码:

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include<stdio.h>
#include<math.h>
#include<string.h>
const int maxn =2e5+10;
typedef long long ll;int tree[maxn<<2];
int a[maxn];
int n,m;void build(int node,int l,int r){if(l==r){tree[node]=a[l];return ;}int mid=(l+r)/2;if(l<=mid) build(node*2,l,mid);if(r>mid) build(node*2+1,mid+1,r);tree[node]=tree[node*2]&tree[node*2+1];
}int query(int node,int start,int ends,int l,int r){if(start>=l&&ends<=r){return tree[node];}int mid=(start+ends)/2;int ans=-1;if(l<=mid)  ans=ans&query(node*2,start,mid,l,r);if(r>mid)   ans=ans&query(node*2+1,mid+1,ends,l,r);return ans;}int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&a[i]);}build(1,1,n);for(int i=0;i<m;i++){int l,r;scanf("%d%d",&l,&r);printf("%d\n",query(1,1,n,l,r));}return 0;}

B:别看了 这是水题

题解:
这个题目算是一个构造题,按照题目要求构造出一个序列。
解法肯定会有很多种,当然不同解法输出的序列也不一样,这里介绍一种解法。

首先判断它是否能构成这样的序列。
如果k∗2<=nk*2<=nk∗2<=n,那么可以构成,反之输出-1.(别问我为什么)

那么我们接下来就需要找一个通用的顺序来输出一下这个序列了。

解法1: 将序列拦腰斩断,分成两半,左边输出一个值,右边输出一个值(重复操作),以保证间隔大于等于k。

复杂度分析:
时间复杂度:O(n)O(n)O(n)
空间复杂度:O(n)O(n)O(n)

解法1代码:

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include<stdio.h>
#include<math.h>
#include<string.h>
const int maxn =2e5+10;
typedef long long ll;int main(){int t;scanf("%d",&t);while(t--){int n,k;scanf("%d%d",&n,&k);if(n==1){   //特判长度1的序列printf("1\n");}else if(k*2<=n){int temp=n/2;if(n%2==1){   //长度为奇数时for(int i=2;i<=temp+1;i++){printf("%d %d ",i+temp,i);}printf("1\n");}else{   //长度为偶数时for(int i=1;i<=temp;i++){printf("%d %d ",i+temp,i);}printf("\n");}}else printf("-1\n");}return 0;}

代码2:

许金龙大神’s code:

#include<bits/stdc++.h>using namespace std;int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int T; cin >> T;while(T --) {int n, k; cin >> n >> k;if (n == 1) cout << "1\n";else if (n < 2*k) cout << "-1\n";else {for(int i = k; i >= 1; -- i) {for(int j = i; j <= n; j += k) {cout << j << " ";}}cout << "\n";}}return 0;
}

C:ACM脱单大法

题解:
这个题目的解法也有很多,因为复杂度卡的不是很严格,时间复杂度O(nlogn)O(nlogn)O(nlogn)应该都可以
比如说二分+暴力,后缀处理等。。

解法:

简单的小贪心做一下(算半个贪心。
首先,如果有解,那么前半部分和后半部分的最大最小值肯定跟整个序列最大最小值是相同的。
这样我们先遍历一遍序列找出最大值和最小值,前半段区间最大最小值和后半段区间最大最小值肯定跟整个序列的相同。
我们遍历一边序列记录下来第一个出现imax的位置maxpos和imin的位置minpos。
设x=max(maxpos,minpos)x=max(maxpos,minpos)x=max(maxpos,minpos)然后从序列x+1这个位置遍历序列,如果存在值等于最大值和存在值等于最小值,那么x就是答案,反之则输出-1。

复杂度分析:
时间复杂度:O(n)O(n)O(n)
空间复杂度:O(n)O(n)O(n)
代码:

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include<stdio.h>
#include<math.h>
#include<string.h>
#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) < (b) ? (a) : (b))
const int maxn =1e5+10;
typedef long long ll;int a[maxn];signed main(){//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);int imax=-2e9-10,imin=2e9+10;int maxpos,minpos;for(int i=1;i<=n;i++){scanf("%d",&a[i]);if(imax<a[i]) imax=a[i],maxpos=i;if(imin>a[i]) imin=a[i],minpos=i;}int st=max(maxpos,minpos);bool xx=false,yy=false;for(int i=st+1;i<=n;i++){if(imax==a[i]) xx=true;if(imin==a[i]) yy=true;}if(xx&&yy) printf("%d\n",st);else printf("-1\n");}
}

D:Love_Jacques学长的游戏思维

坑点1:

实数都有小数点吗?

坑点2: 1.23与1.2300000

题解: 因为实数小于10,所以从左边往右边比较即可,注意一下不同长度字符串的处理,可以把较短的字符串后面全补为0。

复杂度分析:
时间复杂度:O(n)O(n)O(n)
空间复杂度:O(n)O(n)O(n)
代码:

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include<stdio.h>
#include<math.h>
#include<string.h>
#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) < (b) ? (a) : (b))
const int maxn =1e5+10;
typedef long long ll;char s[1100],s1[1100];signed main(){//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);int t;scanf("%d",&t);  //x的值  分别代表谁大谁小while(t--){scanf("%s",s);scanf("%s",s1);int lens=strlen(s);int lens1=strlen(s1);if(lens==1) s[1]='.',s[2]='\0',lens++;   //判断给出的是个整数还是实数,如果是实数则补全if(lens1==1) s1[1]='.',s1[2]='\0',lens1++;if(lens<lens1) for(int i=lens;i<lens1;i++) s[i]='0';  //补0else for(int i=lens1;i<lens;i++) s1[i]='0';int x=0;for(int i=0;i<max(lens1,lens);i++){if(s[i]>s1[i]){   //判断大小,别忘记breakx=1;break;}else if(s[i]<s1[i]){x=2;break;}}if(x==0) printf("EASY GAME!\n");else if(x==1) printf("AZNB\n");else printf("YZNB\n");}
}

E:后缀自动机next指针dag图上跑SG函数

题解:
贪心
考虑并且购买第i个宝石的价格是i∗a[i]。i*a[i]。i∗a[i]。
那么我们不断拿第一个宝石即可。
但是宝石的价格可能是负数,所以遇到价格位负数的宝石(倒贴你钱),我们如何最大化他的值呢,题目可知,想让他倒贴给你钱最多,也就是这个宝石初始位置下标乘a[i]即可。
也可以理解为,先从后往前把小于零的宝石买掉,然后在第一个位置一直买即可。

复杂度分析:
时间复杂度:O(n)O(n)O(n)
空间复杂度:O(1)O(1)O(1)

代码:

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include<stdio.h>
#include<math.h>
#include<string.h>
#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) < (b) ? (a) : (b))
const int maxn =1e5+10;
typedef long long ll;signed main(){//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);int n;scanf("%d",&n);ll ans=0;for(int i=1;i<=n;i++){ll x;scanf("%lld",&x);if(x<0) ans+=x*i;else ans+=x;}printf("%lld",ans);return 0;
}

F:新建 Microsoft PowerPoint 演示文稿.pptx

题解:
暴力即可,设一个数组记录所有出现过的数有哪些,每次从1开始找最小没有出现过的数是什么。

复杂度分析:
时间复杂度:O(n2)O(n^2)O(n2)
空间复杂度:O(n)O(n)O(n)

代码:

/*Keep on going Never give up*/
//#pragma GCC optimize(3,"Ofast","inline")
#include <stdio.h>
typedef long long ll;
const int mod = 1e9+7;
int a[1000+10];
int se(){   //查找未出现过的最小下标for(int i=1;i<=1000;i++){if(!a[i]) return i;}return -1;
}int main(){int n;scanf("%d",&n);for(int i=0;i<1000;i++) a[i]=0;  //可写可不写(全局变量初始值为0,可以不写while(n--){int opt,x;scanf("%d",&opt);if(opt==1){int pos=se();a[pos]=1;   //标记该结点出现过,为后面删除提供遍历if(pos==1) printf("新建 Microsoft PowerPoint 演示文稿.pptx\n");else printf("新建 Microsoft PowerPoint 演示文稿(%d).pptx\n",pos);}else{scanf("%d",&x);if(a[x]){   //查询该结点是否出现过。printf("Successful\n");a[x]=0;}else printf("Failed\n");}}return 0;
}

ps:这个题也有更优的解法,用优先队列即可,学有余力的同学可以尝试一下,思想就是是,一开始把所有未出现的文档全都塞到优先队列中(小顶锥),每次取优先队列头,然后删除优先队列头节点,如果遇到删除改结点,如果这个结点存在,再把这个结点塞进优先队列即可。

复杂度分析:
时间复杂度:O(nlogn)O(nlogn)O(nlogn)
空间复杂度:O(n)O(n)O(n)

代码:

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<bits/stdc++.h>
const int maxn =2e5+10;
typedef long long ll;
using namespace std;
int visited[maxn];
signed main(){//    freopen("27.in","r",stdin);
//    freopen("27.out","w",stdout);int n;cin>>n;memset(visited,false,sizeof visited);priority_queue<int,vector<int>,greater<int>> q;for(int i=1;i<=n;i++){   //未出现的全部塞进优先队列q.push(i);}for(int i=0;i<n;i++){int opt,x;scanf("%d",&opt);if(opt==1){int t=q.top();   //每次取最小元素q.pop();visited[t]=true;if(t==1) printf("新建 Microsoft PowerPoint 演示文稿.pptx\n");else{printf("新建 Microsoft PowerPoint 演示文稿(%d).pptx\n",t);}}else{scanf("%d",&x);if(visited[x]){printf("Successful\n");visited[x]=false;q.push(x);   //删除了改元素,把元素重新放回优先队列。}else printf("Failed\n");}}return 0;
}

G:禁止复读

题解:
用一下c++的sort是我最后写c语言报告的倔强了,不会的同学学一下嘛,真的很好用QAQ。

这个只要搞清楚如何判断一个人是否发起复读是最重要的事情。
假设你要判断第i个人是否为复读发起者
那么你就要检查一下第i-1个人说的话是不是跟他一样
并且第i-2个热播说的话跟他不一样
如果这两者都符合,那么这个人就是复读发起者。

还有一点就是去重,可能一个人会复读好几次,但是你只需要输出一次他的序列即可。
你可以设置一个数组记录已经被记录下来的人,也可以最后对序列进行去重即可。

复杂度分析:
时间复杂度:O(∣s∣∗n)O(|s|*n)O(∣s∣∗n)
空间复杂度:O(∣s∣∗n)O(|s|*n)O(∣s∣∗n)

代码:

/*Keep on going Never give up*/
//#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>char s[1010][55];
int visited[1010];int ans[1010];int judge(char a[],char b[]){int lena=strlen(a);int lenb=strlen(b);if(lena!=lenb) return 0;for(int i=0;i<lena;i++) if(a[i]!=b[i]) return 0;return 1;
}int main(){//    freopen("1.in","r",stdin);
//    freopen("1.out","w",stdout);int n,cnt=0;scanf("%d",&n);for(int i=2;i<=n+1;i++){int opt;scanf("%d",&opt);scanf("%s",s[i]);if(judge(s[i],s[i-1])&&!judge(s[i],s[i-2])){if(!visited[opt]){visited[opt]=1;ans[cnt++]=opt;}}}std::sort(ans,ans+cnt);printf("%d\n",cnt);for(int i=0;i<cnt;i++) printf("%d ",ans[i]);printf("\n");}

H:吓得我赶紧出了个签到题

那串代码得意思:
其实是个splay,平衡树的一种,花里胡哨的一顿乱操作其实没啥用处。
为什么会输出lcltql!是因为对这个数每次添加一个结点(正整数),然后对树进行求和操作,一共求和了七次(当然也添加了七次,每添加一次求和一次),让着七次的值正好等于每个字母对应的ASCII码即可。

/*Keep on going Never give up*/
//#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
#define int long long
#define fin(filename) freopen(filename,"r",stdin)
#define fout(filename) freopen(filename,"w",stdout)
#define endl '\n'
#define Accepted 0
#define AK main()
#define I_can signed
using namespace std;
const int maxn =2e5+10;
const int MaxN = 1e9+7;
const int MinN = -1e9+7;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll mod=1e8;
const int N = 5e6 + 100;signed main(){//    freopen("1.in","r",stdin);
//    freopen("1.out","w",stdout);
//    ios::sync_with_stdio(false);
//    cin.tie(0);
//    cout.tie(0);cout<<"ACDA"<<endl;cout<<"lcltql!"<<endl;
}

2020级HAUT新生周赛(四)@张承树专场相关推荐

  1. 湘阴一中2021高考成绩查询,湘阴一中2020级高一新生录取名单出炉!(附湘阴县高中录取情况)...

    原标题:湘阴一中2020级高一新生录取名单出炉!(附湘阴县高中录取情况) - 2020年的第219天 - 亲爱的同学: 热烈祝贺你经过初中三年的努力,终于被百年名校.省级示范高中--湘阴一中录取.希望 ...

  2. 川大计算机学院新生开学典礼,网络空间安全学院2020级本科新生开学典礼顺利召开...

    2020年9月21日下午两点整,四川大学网络空间安全学院本科新生开学典礼正式召开.网络空间安全学院常务副院长陈兴蜀教授.直属党支部书记兼副院长秦燕教授.副院长刘嘉勇教授.副院长杨频教授.学生科科长黎红 ...

  3. 计算机学院2022级新生周赛(一)题解

    更好的阅读体验\color{red}{更好的阅读体验}更好的阅读体验 另一篇题解\color{red}{另一篇题解}另一篇题解 文章目录 A. Hello , HAUE B. 我必须立刻签到,因为它有 ...

  4. 武汉大学计算机学院卓工班,计算机学院2020级“卓越工程师”班学生选拔方案...

    计算机学院为培养高级工程应用型人才设立"卓越工程师"班,现拟在全院2020级本科新生中招收60名具有计算机领域卓越工程师培养潜力的学生,其中计算机科学与技术专业30名,软件工程专业 ...

  5. 2020年SWPUACM团队新生第四次周赛(题解)

    说好了是新生周赛,一群大二的来凑什么热闹- 还有就是题都不难,但是大一们做的都有点难受- A我是签到题 记得开long long,如果矩形长大于等于宽的三倍,则正方形边长最长为宽:反之,正方形 边长最 ...

  6. 浙二大数据朱继红_快看!浙经贸2020级新生趣味大数据来咯!

    我们开学啦 "滴滴! 您所乘坐的列车已到站 请所有乘客拿好自己的行李 准备下车集合! 久违的欢笑声充斥着寂静的校园 热闹的氛围也逐渐浓郁 2020级"乘客" 已集合完毕! ...

  7. idea2018 2020_新生2020级数字艺术系学生作品展

    新生-2020级数字艺术系学生作品展 2020.10.19 - 2020.11.23 策展人 Curator / 陈洁颖 Chen Jieying 开幕时间 Opening time / 2020.1 ...

  8. 山东大学 2020级数据库系统 实验四

    What's more 山东大学 2020级数据库系统 实验一 山东大学 2020级数据库系统 实验二 山东大学 2020级数据库系统 实验三 山东大学 2020级数据库系统 实验四 山东大学 202 ...

  9. 计算机学院新生入学致辞,计算机学院召开2020级新生入学教育启动大会

    新生入学教育是整个大学教育的起点,是大学思想政治教育的重要组成部分.为切实做好2020级新生入学教育工作,9月22日晚,计算机学院召开入学教育启动大会.院领导.辅导员班主任.教师代表.学生代表以及全体 ...

最新文章

  1. C++/CLI Winform中调用DLL的三种方法
  2. 胶囊网络(Capsule Network)在文本分类中的探索
  3. Linux之ubuntu的root无法连接FTP
  4. android四个按钮平分,android 水平平分两个按钮
  5. libevent简介和使用
  6. 确保您的Silverlight 1.0运行时间组件是最新版本
  7. 超给力,抛弃手动维护,一键生成数据库文档、支持多种格式!
  8. 基于JAVA+SpringMVC+MYSQL的旅行社管理系统
  9. pandoc讲html转换为pdf,将HTML表格转换为PDF的Pandoc会导致非包装表格
  10. opencv方框内图像保存_opencv 图像滤波(均值,方框,高斯,中值)
  11. UVA11270 Tiling Dominoes —— 插头DP
  12. java 泛型(generics)使用总结
  13. 项目日报模板_聪明的项目经理,都会利用周报让老板重视你
  14. TIS-prescan
  15. js中 push pop shift unshift使用的小问题
  16. 又赚了!分享几个我常去的私活接单平台
  17. LSD直线检测和霍夫线变换的学习建议
  18. vue3项目源码汇集
  19. hadoop slaves
  20. 建设网络强国“三步走”战略

热门文章

  1. python获取进程编号(目的、获取当前进程编号、根据编号杀死指定进程号、获取当前父进程编号)
  2. MATLAB利用YCBCR切割出人脸头像
  3. 下面是DHCP协议工作的4种消息,正确的顺序应该是(40)。【答案】B
  4. 仅用CPU就能跑到1000FPS,这是开源的C++跨平台人脸检测项目
  5. 在自定义的数据集上训练YOLOv5详细教程分享
  6. 从numpy开启Python数据科学之旅
  7. Sqoop数据迁移原理及基本框架
  8. 阿里巴巴首部记录片问世:看哭所有创业者!
  9. thinkphp5项目--企业单车网站(七)
  10. 编程十年的十种武学境界