nhoi2022初中组

总结

前四题都挺简单的,5、6题还是算了吧。

话说我自己去考好像也能拿初一的一等奖(doge)。

T1

质约数

这题啊,其实可以用 分解质因数 去写啊。复杂度只要 OnO\sqrt n

但是,反正数据量小,写上个埃氏筛也可以(如果这个质数能筛掉 n ,就直接输出)。复杂度 O(nloglogn)O(nloglogn)

代码

#include<bits/stdc++.h>
using namespace std;
int n;
bool vis[1111111];
int main(){
	cin>>n;
	for(int i=2;i<=n;i++) {
		if(!vis[i]) {
			for(int j=1;i*j<=n;j++) {
				vis[i*j]=true;
				if(i*j==n) cout<<i<<" ";
			}
		}
	}
	return 0;
}

还有某位热心同学的分解质因数:

#include<bits/stdc++.h>
using namespace std;
void cf(int x){
	int x2=x;
	for(int i=2;i<=x;i++){
		bool out=false;
		while(x%i==0){
			x/=i;
			if(!out){
				cout<<i<<" ";
				out=true;
			}
		}
	}
}
int main(){
	int n;
	cin>>n;
	cf(n);
	return 0;
}

T2

好题

这题纯粹就是暴力,但是就是考验细节。

如果数组只开 10610 ^ 6 并且不考虑边界问题的话,会 RE 。

可以把数组开大一点,或在判断的时候防止越界。

代码

#include<bits/stdc++.h>
using namespace std;
int n,m,a[1111];
bool w[11111111];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) {
		cin>>a[i];
		w[a[i]]=true;
	}
	for(int i=1;i<=n+1;i++) {
		for(int j=i+1;j<=n+1;j++) {
			for(int k=j+1;k<=n+1;k++) {
				w[a[i]+a[j]+a[k]]=true;
			}
		}
	}
	int ans=0;
	for(int i=1;i<=m;i++) {
		if(w[i]) ans++;
	}
	cout<<ans;
	return 0;
}

这里使用的是把数组开大的版本。

T3

回文串

下标类问题。这种问题可能试几次就知道结论,但是不能证明的话就不算真正懂这种题。

其实可以通过假设去做。

现有一个字符串 s;

s1 s2 s3 ······ si-2 si-1 si

假设 sx 是完美下标,我们将其删除。

s1 s2 s3 ···sx··· si-2 si-1 si

s1 s2 s3 ···sx+1 sx+2 ··· si-2 si-1 si

此时就可以隐隐约约发现 s1 还是对应 si 。

以此类推,一直到 sx 对应 sy 时出现不同。因为此时 sx 没了,所以其实是sx+1来对应 sy , sx+2 对应 sy-1 ······。

说明 sx=sy,sx+1=sy-1 ······。

而且 sx+1=sy,sx+2=sy-1 ······。

这就把整个串起来了,等于说是 sx=sx+1=sy=sy-1 ······。也就是说 sx ~ sy都是相等的。而且 x ~ y 是对称的 , x 在这边的哪头, y 则在另一头。

所以只要找到符合条件的就可以了,并且大的区间可以满足,小的区间肯定可以满足。我们只需要找到最小的 x ,最大的 y 就可以了。

代码

#include<bits/stdc++.h>
using namespace std;
int n,x,y;
char a[1111111];
int main(){
	cin>>n;
	cin>>(a+1);
	for(int i=(n+1)/2;i>=1;i--) {
		if(a[i]!=a[i-1]){ x=i;break;}
	}
	for(int i=(n+1)/2;i<=n;i++) {
		if(a[i]!=a[i+1]){y=i;break;}
	}
	cout<<y-x+1;
	return 0;
}

T4

变数

这题其实就是搜索,要求的是一共能到达几个数,不是总共的方案数,加上记忆化防超时、就可以了。

代码

#include<bits/stdc++.h>
using namespace std;
bool vis[5111][5111];
int s,n,ans,flag;
void f(int x,int v) {//数字,使用的次数
	if(v==n) {
		ans++;
		return ;
	}
	if(x%2==0) {
		if(!vis[x/2][v+1]) {
			vis[x/2][v+1]=true;
			f(x/2,v+1);
		}
	}
	x=(x)?(x):(1);
	if(!vis[x-1][v+1]) {
		vis[x-1][v+1]=true;
		f(x-1,v+1);
	}
} 
int main(){
	cin>>s>>n;
	f(s,0);
	cout<<ans;
	return 0;

本文作者:cjrqwq

本文链接:https://www.cnblogs.com/yfzqwq/p/18492844

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   cjrqwq  阅读(30)  评论(0编辑  收藏  举报  
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
展开
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.