又快到了一年一度的蓝桥杯省赛了,作为一个小萌新,自己复习一些蓝桥杯的算法并分享给大家。
bool isleaf(int x){
return x%400==0||(x%4==0&&x%100!=0);
}
计算日的算法如下,小时分钟和秒就是在此基础上乘以相应的进制即可,月份就是在模板里面month++的时候顺便计数即可。
int syear,smonth,sday; //分别为结束年,月,日
int countday(int year,int month,int day){ //分别为开始的年月日
int ans=0;
int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
while(1){
if(year==syear&&month==smonth&&day==sday){
break;
}
day++;
if(isleaf(year)&&month==2){
if(day>mon[month]+1){
month++;
day=1;
}
}else{
if(day>mon[month]){
month++;
day=1;
}
}
if(month>12){
month=1;
year++;
}
ans++;
}
return ans;
}
筛选素数有许多种方法,首先是最简单的O(n^(3/2))的算法
bool isprime(int n){
if(n==1)return false;
for(int i=2;i*i<n;i++){
if(n%i==0)return false;
}
return true;
}
埃氏筛法O(nloglogn)
埃氏筛法的基本思想:从2开始,将每个质数的倍数都标记成合数,以达到筛选素数的目的
bool visit[MAXN];
void prime(){
memset(visit,false,sizeof(visit); //初始化
visit[0]=visit[1]=true;
for(int i=2;i<=MAXN;i++){
if(!visit[i]){
for(int j=i*i;j<MAXN;j+=i){
visit[j]=true;
}
}
}
}
bool isprime(int n){
return !visit[n];
}
但经过测试埃氏筛在超过100000之后效率不佳,于是就有了欧拉筛
思想:在埃氏筛的基础之上,让每个合数只被最小质因子筛选一次,以达到不重复。
int prime[MAXN];
int visit[MAXN];
void olprime(){
memset(visit,0,sizeof(visit));
memset(prime,0,sizeof(prime));
for(int i=2;i<=MAXN;i++){
if(!visit[i]){
prime[++prime[0]]=i;
}
for(int j=1;j<=prime[0]&&i*prime[j]<=MAXN;j++){
visit[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int lcm(int a,int b){
return a*b/gcd(a,b);
}
int gcds(int a[],int n){
int g=a[0];
for(int i=1;i<n;i++){
g=gcd(g,a[i]);
}
return g;
}
int lcms(int a[],int n){
int l=a[0];
for(int i=1;i<n;i++){
l=lcm(a[i],l);
}
return l;
}
#include
using namespace std;
int main(){
int v[MAXN],w[MAXN],dp[MAXN];
int m,n;//m为总背包大小,n为物品个数
cin>>m>>n;
for(int i=1;i<=n;i++){
cin>>v[i]>>w[i];
}
for(int i=1;i<=n;i++){
for(int j=m;j>=v[i];j--){
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
}
cout<<dp[m];
}
#include
using namespace std;
int main(){
int v[MAXN],w[MAXN],dp[MAXN];
int m,n;//m为总背包大小,n为物品个数
cin>>m>>n;
for(int i=1;i<=n;i++){
cin>>v[i]>>w[i];
}
for(int i=1;i<=n;i++){
for(int j=v[i];j<=m;j++){
dp[j]=max(dp[j],dp[j-v[i]]+w[i]);
}
}
cout<<dp[m];
}
两个背包问题的区别就是:01背包每个物品只能选一个,而完全背包问题可以多次选一个物品。
#define long long ll
#define mod 1e9+7
ll quickpow(ll a,ll n){
if(n==0||a==1)return 1;
ll ans=1;
while(n!=){
if(n%2==1)ans=a*ans%mod;
a=a*a%mod;
n>>1;
}
return ans;
}
long long C(int n,int m){
if(m==0)return1;
long long ans=1;
for(int i=n;i>n-m;i--)ans*=i;
for(int i=m;i>1;i--)ans/=i;
return ans;
}
这个算法的缺点在于如果会溢出,long long类型的数字到(83,41)就不能用了,所以我们借助大数
全排列C++有个叫next_permutation()的函数,这个函数的好处在于能够自动去重全排列,但要注意在操作前一定要将数组或者字符串排序,不然得到的结果不完整。
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>> ret;
sort(nums.begin(),nums.end());
do{
ret.emplace_back(nums);
}while(next_permutation(nums.begin(),nums.end()));
return ret;
}
int n,m,cnt=0;
int f[10005];
int find(int x){
if(f[x]==x)return x;
return f[x]=find(f[x]);
}
void union(int x,int y){
int a=find(x);
int b=find(y);
if(a!=b){
f[a]=b;
cnt++;
}
}