时间复杂度
时间复杂度由低到高排列
算法的最终时间复杂度由嵌套层数最多循环语句中最内层语句的频度决定
cin.getline的用法
istream&getline(char name[],int size,char endchar='\n')
可以实现输入特定长度的字符串,若超过特定长度则只取符合长度的,若不超过可用\n控制结束
#include <bits/stdc++.h>
using namespace std;
int main()
{
char a[100];
cin.getline(a,100);
printf("%s",a);
return 0;
}
循环节
求n^n的最后一位,找规律周期
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a[10][4]={{0},{1},{6,2,4,8},{1,3,9,7},{6,4},{5},{6},{1,7,9,3},{6,8,4,2},{1,9}};
long int n,x,y;
while(scanf("%ld",&n)>0)
{
while(n--)
{
scanf("%ld",&x);
y=x%10;
if(y==0||y==1||y==5||y==6)
{
printf("%d\n",y);
}
else if(y==4||y==9)
{
printf("%d\n",a[y][x%2]);
}
else
{
printf("%d\n",a[y][x%4]);
}
}
}
return 0;
}
快速幂取模
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i,n,t;
while(scanf("%d",&n)>0)
{
while(n--)
{
int s=1;
scanf("%d",&t);
for(i=1;i<=t;i++)
s=(s*(t%10))%10;
printf("%d\n",s);
}
}
return 0;
}
求n!的位数
一个数n的位数可以用lg(n)+1表示
#include <bits/stdc++.h>
using namespace std;
int main()
{
long int i,n;
while(scanf("%ld",&n)>0)
{
double sum=0.0;
for(i=2;i<=n;i++)
{
sum=sum+log10(i);
}
printf("%ld\n",(long int)sum+1);
}
return 0;
}
求n^n的最左边的数
#include <bits/stdc++.h>
using namespace std;
int main()
{
long int n,t;
double x=0.0;
while(scanf("%ld",&n)>0)
{
while(n--)
{
scanf("%ld",&t);
x=t*log10(double(t));
x=x-(long long)x;
x=(int)pow(10,x);
printf("%.0lf\n",x);
}
}
return 0;
}
sort
头文件:algorithm.h
复杂度:n*log(n)
升序:sort(a,a+n,less< data-type >())
降序:sort(a,a+n,greater< data-type >())
循环节
nefu-67
#include <bits/stdc++.h>
using namespace std;
int main()
{
int f[101],a,b,n,i;
while(cin>>a>>b>>n)
{
f[1]=1;
f[2]=1;
if(a==0&&b==0&&n==0)
break;
if(n<3)
cout<<"1"<<endl;
else
{
for(i=3;i<=49;i++)//自动找出循环节
{
f[i]=(a*f[i-1]+b*f[i-2])%7;
if(f[i]==1&&f[i-1]==1)
break;
}
n=n%(i-2);//注意下标
if(n==0)
cout<<f[i-2]<<endl;
else
cout<<f[n]<<endl;
}
}
return 0;
}
nefu-519
f(n)=1^2+ 2^2+…+n ^ n=(1/6) * n * (n+1)(2n+1)
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n,ans,t;
while(cin>>n)
{
t=n*(n+1)/2;//两个连续整数相乘必是一奇一偶,一定可以被二整除
if(t%3==0)
{
t=t/3;
ans=(t%1007)*((n*2+1)%1007);
ans=ans%1007;
}
else//因为最后结果一定是整数,所以如果t不能被三整除那么2*n+1一定可以
{
ans=(2*n+1)/3;
ans=ans%1007;
ans=(t%1007)*ans;
ans=ans%1007;
}
cout<<ans<<endl;
}
return 0;
}
nefu-763
n!的末尾有几个0,因为2*5=10,所以求2,5的对数,又因为5的个数少,所以求n!中5的个数。
举例:100
100/5=20 说明100之前有20个可以被五整除的数
100/5/5=4 说明100之前有4个可以被25整除的数,而25可以分解成两个5
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,ans;
while(cin>>n)
{
ans=0;
while(n)
{
n=n/5;
ans+=n;
}
cout<<ans<<endl;
}
return 0;
}
nefu-901
#include <bits/stdc++.h>
using namespace std;
int main()
{
double a[100001];
int n;
double s1,s2;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lf",&a[i]);
sort(a,a+n);
while(scanf("%lf %lf",&s1,&s2)>0)
{
int ans=upper_bound(a,a+n,s2)-lower_bound(a,a+n,s1);
printf("%d\n",ans);
}
return 0;
}
容易出错的地方
Int ans=lower_round(a,a+n,x)
这样是错误的!
正确的写法:
Int ans=lower_round(a,a+n,x)-a;
因为lower_round()返回的是指针,而不是int
二分
nefu-899
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,k,ans,l,r,mid;
while(scanf("%d %d",&n,&k)>0)
{
ans=0;l=1;r=n;
while(l<=r)
{
ans++;
mid=(l+r)/2;
if(mid==k)
break;
if(mid<k)
l=mid+1;
if(mid>k)
r=mid-1;
}
printf("%d\n",ans);
}
return 0;
}