23级寒假预备役第三次测试

额外知识点:

0x3f:代表的数值63

0x3f3f:代表的数值16191 10的四次方多

0x3f3f3f:代表的数值4144959 10的六次方多

0x3f3f3f3f:代表的数值1061109567 10的九次方多

1.题目:选数

输入:

4 3
3 7 12 19

输出:

1

dfs

#include<bits/stdc++.h>        //万能头文件
using namespace std;
int n,m;
int a[100],b[100];
int f(int x) {
	for(int i=2; i*i<=x; i++) {
		if(x%i==0)
			return 0;
	}
	return 1;
}
int ans=0,num=0,t=0;
void dfs(int x,int y) {
	if(x==m+1) {
		if(f(t)==1) {
			num++;
		//	printf("%d %d %d\n",t,num,x);
		}
	} else {
		for(int i=1; i<=n; i++) {
			if(x==1&&i>n-m+1)
				continue;
			if(b[i]==0&&i>y) {
				t+=a[i];
				b[i]=1;
				dfs(x+1,i);
				t-=a[i];
				b[i]=0;
			}
		}
	}
}
int main() {
	cin>>n>>m;
	for(int i=1; i<=n; i++)
		cin>>a[i];
	dfs(1,0);
	printf("%d",num);
	return 0;
}

2.题目:奇怪的电梯

输入:

5 1 5
3 3 1 2 5

输出:

3

写了两种方法,这是dfs。

#include<bits/stdc++.h>
using namespace std;
int n,a,b,k[201],dis[201];
void dfs(int m,int t) {
	dis[m]=t;//一定可以更新
	int v=m-k[m];
	if(v>=1&&t+1<dis[v])//可以更新在搜索)下
		dfs(v,t+1);
	v=m+k[m];
	if(v<=n&&t+1<dis[v])//上
		dfs(v,t+1);
	return;
}
int main() {
	memset(dis,0x3f3f3f3f,sizeof(dis));//给整个数组赋值
	cin>>n>>a>>b;
	for(int i=1; i<=n; i++)
		cin>>k[i];
	dfs(a,0);
	cout<<(dis[b]==0x3f3f3f3f?-1:dis[b]);  //看是不是一直搜索,是的话就无法到达指定楼层
	return 0;
}

这是bfs。

#include<bits/stdc++.h>
using namespace std;
int a[220];
bool vis[220];
int main(){
	int n,s,e;
	cin>>n>>s>>e;
	if(s==e){//初始楼层和目标楼层相同,不需要按电梯 
		cout<<0;
		return 0;
	} 
	for(int i=1;i<=n;i++)
	cin>>a[i];
	
	queue<int>q;      //构建队列
	q.push(s);        //入列
	int t=0;vis[s]=1;//标记,已经走过了
	while(++t){       //计步
		int x=q.size();//队列q的元素个数
		if(x==0){     //空了
			cout<<-1;
			return 0;
		}
		for(int i=0;i<x;i++){//将当前 q 中所有状态向前推一遍
			int p=q.front();
			q.pop();
			if(p-a[p]>=1){        //按下键时电梯不会跑到地底下 (下)
				if(!vis[p-a[p]]){ //这个状态没被访问过 
					if(p-a[p]==e){ //到目标楼层啦 
						cout<<t;
						return 0;
					} 
					vis[p-a[p]]=1;//标记走过了
					q.push(p-a[p]);//入列
				}
			}
			
			if(p+a[p]<=n){       //按上键时电梯不会超过顶层 (上)
				if(!vis[p+a[p]]){//这层楼没被来过
					if(p+a[p]==e){//到达目标楼层啦
						cout<<t;
						return 0;
					} 
					vis[p+a[p]]=1;
					q.push(p+a[p]);
				}
			}
		}
	}
	return 0;
}

3.题目:

输入:

7
AtCoder
5
1 4 i
3 0 a
1 5 b
2 0 a
1 4 Y

输出:

atcYber

输入 :

35
TheQuickBrownFoxJumpsOverTheLazyDog
10
2 0 a
1 19 G
1 13 m
1 2 E
1 21 F
2 0 a
1 27 b
3 0 a
3 0 a
1 15 i

输出:

TEEQUICKBROWMFiXJUGPFOVERTBELAZYDOG

好好想想

#include<bits/stdc++.h>
using namespace std;
char s[500005];
int a[500005];
int b[500005];
int n,t,r,q;
char c[500005];
int main() {
	cin>>n>>s>>q;
	for(int i=0; i<q; i++) {
		scanf("%d %d %c",&a[i],&b[i],&c[i]);
		if(a[i]==2) {
			t=i;
		} else if(a[i]==3) {
			t=i;
		}                          //提前知道到第i次变化时字符串是大写还是小写了,可以大大缩短中间小写变大写,大写变小写的时间
	}                              //因为这个时候字符串还短,交上去测试数据是字符有临界值那么大,时间就会变得很多,所有交上去会显示时间超限
	for(int i=0; i<q; i++) {
		if(i==t) {                 //只要一次大小写变化就好了,要不然会多了好多个for(int i=0; i<n; i++)循环,时间成倍增加
			if(a[i]==2) {
				for(int i=0; i<n; i++) {
					if(s[i]>='A'&&s[i]<='Z')
						s[i]+=32;
				}
			} else  {
				for(int i=0; i<n; i++) {
					if(s[i]>='a'&&s[i]<='z')
						s[i]-=32;
				}
			}
		}
		if(a[i]==1)           //只有这个改变才会具体打字符串的单个字符
			s[b[i]-1]=c[i];
	}
	printf("%s",s);
	return 0;
}

4.题目:纠错

输入:

5 ababc
ababc
babc
abacbc
abdbc
abbac

输出:

4
1 2 3 4

输入:

1 aoki
takahashi

输出:

0

输入:

9 atcoder
atoder
atcode
athqcoder
atcoder
tacoder
jttcoder
atoder
atceoder
atcoer

输出;

6
1 2 4 7 8 9

现在还没有写出来,对一半的代码,可以看看。

#include<bits/stdc++.h>        //万能头文件
using namespace std;
int n,num=0,r;
const int N=1e5+10;
char a[N];
int ty[N];
char b[N][N/10];
int p(int x,int y) {
	if(y==1) {
		for(int i=0; i<r-1; i++) {
			int t=0;
			if(a[i]!=b[x][i]) {

				for(int j=i+1; j<r; j++)
					if(a[j]!=b[x][j-1])
						t=1;
			}
			if(t)return 0;
		}
		return 1;
	} else {
		for(int i=0; i<strlen(b[x])-1; i++) {
			int t=0;
			if(a[i]!=b[x][i]) {
				for(int j=i+1; j<strlen(b[x]); j++)
					if(b[x][j]!=a[j-1])
						t=1;
			}
			if(t)return 0;
		}
		return 1;
	}
}
void f(int x) {
	if(x>n)return;
	else {
		int l=strlen(b[x]),t=0,sum=0;
		if(r-l==1) {
			if(p(x,1))
				//	printf("%d ",x);
				ty[++num]=x;
			f(x+1);
		} else if(l-r==1) {
			if(p(x,2))
				//	printf("%d ",x);
				ty[++num]=x;
			f(x+1);
		}

		else if(r-l==0) {
			int t=0;
			for(int i=0; i<r; i++) {
				if(a[i]!=b[x][i])    //改变
					t++;
			}
			if(t<=1)
				//	printf("%d ",x);
				ty[++num]=x;
			f(x+1);
		} else
			f(x+1);
	}
}
int main() {
	cin>>n>>a;
	if(n==1)
	char b[10][N];
	for(int i=1;i<=n;i++)
		cin>>b[i];
	r=strlen(a);
	f(1);
	printf("%d\n",num);
	for(int i=1; i<=num; i++)
		printf("%d ",ty[i]);
	return 0;
}

5.题目:平方排列

输入:

4
4320

输出:

2

输入:

3
010

输出:

2

输入:

13
8694027811503

输出:

840

6.题目:旋转彩色子序列

输入:

8 3
apzbqrcs
1 2 3 1 2 2 1 2

输出:

cszapqbr

输入:

2 1
aa
1 1

输出:

aa

7.题目:无限通讯网

输入:

2 4
0 100
0 300
0 600
150 750

输出:

212.13

这个是最小生成树的内容,之前没学,现在ok了,可以去看看。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值