质因子():
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;
}
!(经典双向链表) ![](https://img-blog.csdnimg.cn/direct/189787d74bbb4acf87ed2b51a455b219.jpeg)
菜狗从底层做起: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;
}