week 3

文章详细解释了如何在C++中寻找给定整数的质因子,通过因子判断和质数检查,以及处理字符串操作如查找字符出现次数和字符串拼接的问题。涉及到的算法包括因子遍历、质数判定和一些数据结构的应用。
摘要由CSDN通过智能技术生成

质因子():

12的因子有:1,2,3,4,6,12;

其中,2,3,是质数,所以本题找的是2,3;

整数n的因子,用n分别对1~sqrt(n){因子成对存在}的数除运算,如果整除,那就是因子

伪代码:int n=12,j;

for(j=1;j<=n(无需全部遍历,到中间数即可){可替换为sqrt(n),但是可定义一个变量等于它,这样每次循环不用重复计算};j++){

if(n%j==0) / /  j是n的因子

{
}

}

得出一个因子,就对其进行质素判断

int prime(int n){
    if(n==0)||n==1)return 0;//不是素数
    if(n==2)return 1;//是素数,返回n也行
    int j,m=n/2;
    for(j=2;j<=m;j++)
{
    if(n%j==0)return 0;//非素数
                      }
return 1;经过循环之后,一定是素数

}

AC;                                                                         (理解不了就背吧)(difficult)

#include <bits/stdc++.h>
const int N = 10010;
const int INF = 0x3f3f3f3f;
#define int long long
using namespace std;
void solve() {
    int n;
    cin>>n;
    int ans=0;
    for(int i=2;i<n/i;i++) {
        //12/2=6;6/2=3;3/2
        if(n%i==0) {//如果是因子
            ans++;//i就是质因子
            while(n%i==0){
                n=n/i;
            }//将质因子i从n里去掉
        }
    }
    if(n>1)ans++;//剔除后如果n大于1,说明n本来就是质因子
    cout<<ans<<endl;
}
signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int t = 1;
    while (t--)solve();
    return 0;
}

 字符串中值:

                                                 看完题解 !        

#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long n, k=0;
    char c;
    scanf("%lld %c", &n, &c);
    char a[n+1];
    scanf("%s", a);
    for(long long i=0;i<n;i++)
    {
        if(a[i]==c)
        {
            k++;//字符本身
            int j=min(i,n-i-1);
            k+=j;
        }
    }
    printf("%lld", k);
    return 0;
}

 !(经典双向链表)                                      

                  菜狗从底层做起:AC 代码的搬运工

#include <bits/stdc++.h>
using namespace std;
signed main()
{
    int q,op,x,y;
    map<int,pair<int,int> > mapp;
    mapp[0]={-1,-1};
    cin>>q;
    int cnt=0;
    while(q--){
        cin>>op;
        if(op==1){
            cnt++;
            cin>>x>>y;
            mapp[x]={y,mapp[y].second};
            mapp[mapp[y].second].first=x;
            mapp[y].second=x;
        }
        else{
            cnt--;
            cin>>x;
            mapp[mapp[x].first].second=mapp[x].second;
            mapp[mapp[x].second].first=mapp[x].first;
        }
    }
    cout<<cnt<<endl;
    for(int i=mapp[0].second;i!=-1;i=mapp[i].second){
        cout<<i<<" ";
    }
    return 0;
}

选拔赛L: 

测了五遍,考虑到结尾为a的情况,比如haabdca;那么另一个字符串就是haabdbz;

测试样例8错误;

又考虑到可能有连续为a的,比如haaaaa,那另一个就是gzzzzzz.....

提交,Ok,还是测试样例8;

又想到时aaaaaa,那么另一个字符串就是比他少一个a;

我想可能该过了吧,这么完美了,已经。提交,,

还是浅浅记录一下错误代码吧,以儆效尤                                                           

#include<bits/stdc++.h>  
using namespace std; 	
string a,b;	
int n,m;
bool check(string y){
	for(int i=0;i<n;i++){
		if(a[i]!='a'){
			return 0;
		}
	}
	return 1;
}
int main(){


	cin>>n>>m;
	getchar();
	cin>>a;
	if(n>m){
		cout<<a.substr(0,m);
	}
	else{
		if(check(a)){
			for(int i=0;i<n-1;i++){
				cout<<a[i];
			}
		}
		else if(a[n-1]=='a'){
			for(int i=n-1;i>=0;i--){
				if(a[i]=='a')a[i]='z';
				else if(a[i]!='a'){
					a[i]=a[i]-1;
					break;
				}
			}
			cout<<a;
			int u;
			u=m-n;
			while(u--){
				cout<<'z';
			}		}
		else{
			a[n-1]=a[n-1]-1;
				cout<<a;
			int u;
			u=m-n;
			while(u--){
				cout<<'z';
			}
		}
	
	}
	return 0;
}

 为什么错?因为假设n=8,b=10;

string a=habcdefa;

此时的b不是我理解的habcdeezzz

应该是habcdef   (他才是最大) !!!!!!!!!!!!!!!!

AC:

#include<bits/stdc++.h>  
using namespace std; 
int main(){
	int n,m;
	string a,b;
	cin>>n>>m;
	getchar();
	cin>>a;
	if(n>m){
		cout<<a.substr(0,m);
	}
	else{
		if(a[n-1]=='a'){
			n=n-1;
		}
		else{
			a[n-1]=a[n-1]-1;
			cout<<a;
			int u;
			u=m-n;
			while(u--){
				cout<<'z';
			}
			return 0;
		}
		for(int i=0;i<n;i++){
			cout<<a[i];
			
		}
		
	}
	return 0;
}

选拔赛C题 

 

 当时我的脑子告诉我好复杂(贪心,BFS or DFS??)不会,我信了

当我看到别人的代码时:内心be like: 

                            

草稿模拟一下找找规律; 

AC:

#include<bits/stdc++.h>  
using namespace std; 
int a[1000005];
int main(){
	int n;
	cin>>n;
	if(n<=3||n==6)cout<<"-1"<<endl;
	else if(n==4)cout<<"1 2 1 0"<<endl;
	else if(n==5)cout<<"2 1 2 0 0"<<endl;
	else if(n==7)cout<<"3 2 1 1 0 0 0"<<endl;
	else{
		for(int i=0;i<n;i++){
			if(i==0){
				a[0]=n-4;
			}
			else if(i==1)a[1]=2;
			else if(i==2)a[2]=1;
			else if(i==n-4)a[n-4]=1;
			cout<<a[i]<<" ";
			
		}
		cout<<endl;
	}
	return 0;
}

 选拔赛E题:

 

 

博弈论的题 

只有当尺寸为奇数时姐姐一定会赢,为偶数时zn赢

#include<bits/stdc++.h>
using namespace std;
int main(){
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int T;
    cin>>T;
    while(T--){
        int n;
        cin>>n;
        vector<int> v(n);
        for(int i=0;i<n;i++){
            cin>>v[i];
        }
        if(n%2==0) cout<<"zn"<<endl;
        else cout<<"qcjj"<<endl;
    }
    return 0;
}

冒泡排序+最长子段

 

 

 此题是交换任意两个数字,不是相邻的数字;暴力枚举比较大小即可;

最大子段和:在一段数字中连成的序列中最大的子段中所有数的和的最大子段和

o(n^3)的算法:只有(n<=100);

#include<bits/stdc++.h>
using namespace std;
int main(){
	int a[1001];
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int ans=-0x3f3f3f3f;//负无穷
	for(int i=1;i<=n;i++){//枚举左端点
		for(int j=1;j<=n;j++){//枚举右端点
			int sum=0;//计算这段子段的和
			for(int k=i;k<=j;k++){
				sum+=a[k];
			}
			ans=max(ans,sum);//更新
		}
	}
}

 可以通过写一个前缀和来优化暴力算法.每次枚举一个新的左端点就初始化和变量为0.

然后第二层枚举右端点将和变量加上数组的第右端位,每次操作及时更新最大值,所以一共有两层循环,时间复杂度为O(n^2),可以通过n<=10000的数据。

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int a[1001];
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int ans=-0x3f3f3f3f;//负无穷
	for(int i=1;i<=n;i++){//枚举左端点
			int sum=0;
			for(int j=i;j<=n;j++){//枚举右端点
				sum+=a[j];
				ans=max(ans,sum);
			}
		}
	}

 但是这样还是无法通过n<=1000000甚至更高的数据。所以如果要进行动态规划进行优化;

开一个dp数组,每次状态转移需要判断dp[i-1]是否大于等于0,如果大于等于0那说明前面的子段是可以保留的,再把a[i]接在这后面如果小于0那说明前面这段不是更优的。

需要舍弃,所以这种情况就再开一段,对于这个模板行数比较多的代码是这样写的:

for(int i=1;i<=n;i++){
	if(dp[i-1]>=0){
		dp[i]=dp[i-1]+a[i];
	}
	else{
		dp[i]=a[i];
	}
}

 如果要压行数那可以把状态转移式压成一行。

for(int i=1;i<=n;i++){
	dp[i]=max(dp[i-1]+a[i],a[i]);
}

最后需要取整个dp数组中最大的一项。

int ans=-0x3f3f3f3f;
for(int i=1;i<=;i++){//如果i刚开始设为0就是可以取空子段的意思,因为dp[0]的值为0
ans=max(ans,dp[i]);
}

AC:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define N 200000
ll i,j,k,n,m,t,a[1005],res=-1e18;
void chk(){
	int i,j,k;
	ll mn=0,p=0;
	for(i=1;i<=n;i++){
		p+=a[i];
		res=max(res,p-mn);
		mn=min(mn,p);
	}
}

int main(){
	ios::sync_with_stdio(0); cin.tie(0);
	cin>>n>>m;
	for(i=1;i<=n;i++)cin>>a[i];
	chk();
	if(m)for(i=1;i<n;i++){
		swap(a[i],a[i+1]);
		chk();
		swap(a[i],a[i+1]);
	}
	cout<<res;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值