CSP-J复赛集训专项

1.暴力枚举:

(1)交换字符

#include<iostream>
#include<iomanip>
#include<cmath> 
#include<string>
#include<algorithm> 
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<stack>
using namespace std; 
const int N=1e4+5;
int n,T;
char s[N],t[N];
int main(){
  scanf("%d",&T);
   while(T--){
        scanf("%d%s%s",&n,s+1,t+1);
       vector<char> v1,v2;
       for(int i=1;i<=n;i++){
           if(s[i]!=t[i]){
               v1.push_back(s[i]);
               v2.push_back(t[i]);
           }
       }
       if(v1.size()==2&&v1[0]==v1[1]&&v2[0]==v2[1])  printf("Yes\n");
       else printf("No\n");
   }
	return 0;
}

(2)打怪兽

#include<iostream>
#include<iomanip>
#include<cmath> 
#include<string>
#include<algorithm> 
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<stack>
using namespace std; 
const int N=2e5+5;
int T,n,a[N];
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        long long ans=0;
        for(int i=1,now=1;i<=n;i++){
            if(a[i]<now)   continue;
            ans+=a[i]-now;
            now++;
        }
        printf("%lld\n",ans);
    }
	return 0;
}

(3)摆放棋子

#include<iostream>
#include<iomanip>
#include<cmath> 
#include<string>
#include<algorithm> 
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<stack>
using namespace std; 
int main(){
   int n;
   cin>>n;
   int a[11000];
   for(int i=1;i<=n;i++){
       cin>>a[i];
   }
   cout<<"YES";
	return 0;
}

(4)选取物品

#include<bits/stdc++.h>
using namespace std;
int n,m,k,ans,c[15],w[15],p[25];
int main() {
   scanf("%d%d%d",&n,&m,&k);
   for(int i=1;i<=n;i++)   scanf("%d%d",&c[i],&w[i]);
   for(int i=1;i<=n;i++)  p[i]=i;
   do{
       int sumc=0,sumw=0;
       for(int i=1;i<=k;i++){
           if(sumw+w[p[i]]>m)  break;
           sumc+=c[p[i]],sumw+=w[p[i]];
       }
       ans=max(ans,sumc);
   }while(next_permutation(p+1,p+1+n));
   printf("%d",ans);
	return 0;
 
}

(5)区间翻转

#include<bits/stdc++.h>//递归,离线算法思想
using namespace std;
const int N=1e6+5;
struct node{
    int op,l,r;
}b[N];
int n,q,m,t,a[N];
int solve(int idx,int pos){
    if(idx==0)
        return a[pos];
    int op=b[idx].op,l=b[idx].l,r=b[idx].r;
    if(l<=pos&&r>=pos){
        if(op==1)
            return solve(idx-1,pos==l?r:pos-1);
        else
           return solve(idx-1,l+r-pos);     
     }   
    else
        return solve(idx-1,pos);
}
int main() {
   scanf("%d%d%d",&n,&q,&m);
   for(int i=1;i<=n;i++){
       scanf("%d",&a[i]);
   }
   for(int i=1;i<=q;i++){
       scanf("%d%d%d",&b[i].op,&b[i].l,&b[i].r);
   }
   while(m--){
       scanf("%d",&t);
       printf("%d ",solve(q,t));
   }
    return 0;
}

2.动态规划:

(1)最长上升子序列

#include<bits/stdc++.h>
using namespace std;
int n,ans,pos,a[1005],f[1005],pre[1005];
stack<int> st;
int main() {
	scanf("%d",&n);
	for(int i=1;i<=n;i++)  scanf("%d",&a[i]);
	for(int i=1;i<=n;i++){
		f[i]=1;
		for(int j=1;j<i;j++){
			if(a[j]<a[i]&&f[j]>=f[i]){
				f[i]=f[j]+1;
				pre[i]=j;
			}
		} 
		if(ans<f[i]){
			ans=f[i];
			pos=i;
		}
	}
	printf("%d\n",ans);
	while(f[ans]){
	    st.push(a[pos]);
	    pos=pre[pos];
	}
	while(!st.empty()){
	    printf("%d ",st.top());
		st.pop();
	}
	
		return 0;
}

(2)分组背包

#include<bits/stdc++.h>
#define pii pair<int,int>
using namespace std;
int m,n,t,f[1005];
vector<pii > a[15];
int main() {
	scanf("%d%d%d",&m,&n,&t);
	for(int i=1;i<=n;i++){
		int cc,ww,p;
		scanf("%d%d%d",&ww,&cc,&p);
		a[p].push_back(make_pair(ww,cc));
	}
	for(int i=1;i<=t;i++)
		for(int j=m;j>=0;j--)
			for(int k=0;k<a[i].size();k++)
				if(a[i][k].first<=j)
					f[j]=max(f[j],f[j-a[i][k].first]+a[i][k].second);
			printf("%d\n",f[m]);
		return 0;
}

(3)混合背包

#include<bits/stdc++.h>
using namespace std;
int n,v,m,a,b,c,dp[1005][1005];
int main() {
	cin>>n>>v>>m;
	for(int i=1;i<=n;i++){
		cin>>a>>b>>c;
		for(int j=v;j>=a;j--){
			for(int k=m;k>=b;k--){
				dp[j][k]=max(dp[j][k],dp[j-a][k-b]+c);
			}
		} 
	}
	cout<<dp[v][m]<<"\n";
		return 0;
}

(4)求和比较

#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int n,m,sum,f[N];
int main() {
	scanf("%d%d",&n,&m);
	f[0]=1;
	sum=n*(n+1)/2;
	for(int i=1;i<=n;i++){
	    for(int j=sum;j>=i;j--){
	        f[j]+=f[j-i];
	        }
	}
	int ans=0;
	for(int i=0;i<=sum-i;i++){
	    if((sum-i)-i==m) ans+=f[i];
	}
	printf("%d",ans);
		return 0;
}

(5)吃豆子

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N],n,m;
long long f[N][2];//0今天不吃,1今天吃 
int main() {
   scanf("%d",&n);
   for(int i=1;i<=n;i++){
       int x;
       scanf("%d",&x);
       a[x]++;
       m=max(m,x);
      }
      for(long long i=1;i<=m;i++){
          f[i][0]=max(f[i-1][0],f[i-1][1]);
          f[i][1]=f[i-1][0]+i*a[i];
      }
      printf("%lld",max(f[m][0],f[m][1]));
		return 0;
}

(6)微型火车头

#include<bits/stdc++.h>
using namespace std;
const int N=5e4+5;
int t,n,m,a[N],sum[N],f[4][N];
int main() {
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
           scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        scanf("%d",&m);
        memset(f,0,sizeof(f));
        for(int i=1;i<=3;i++){
          for(int j=m;j<=n;j++){
              f[i][j]=max(f[i][j-1],f[i-1][j-m]+sum[j]-sum[j-m]);
          }
        }
        printf("%d\n",f[3][n]);
    }
		return 0;
}

   (7)老鼠排队

#include<bits/stdc++.h>
#define ll long long;
using namespace std;
const int N=1e6+10;
int n,ans,f[N];
pair<int,int>a[N];
int main() {
      scanf("%d",&n);
	  for(int i=1;i<=n;i++)  scanf("%d",&a[i].first);   
	  for(int i=1;i<=n;i++)  scanf("%d",&a[i].second);   
	  sort(a+1,a+n+1);
	  for(int i=1;i<=n;i++){
	  	f[i]=1;
	  	for(int j=1;j<i;j++){
	  		if(a[i].second<a[j].second){
	  			f[i]=max(f[i],f[j]+1);
			  }
		  }
		  ans=max(ans,f[i]);
	  }
	  printf("%d",ans);
		return 0;
}

暴力骗分:

(1)对拍

 while(t){
	t--;
	system("gen.exe>data.in");
    system("brute.exe<data.in>brute");
    system("std.exe<data.int>std.out");
    if(system("fc brute.out std.out"))
        break;
	
}

(2)Vouchers

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+10;
int n,m,x,has[N];
bool lucky[N],vis[N]; 
vector<ll> ans;
int main() {
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        scanf("%d",&x);
        lucky[x]=1;
    }
    scanf("%d",&n);
    ll cnt=0;
    while(n--){
        scanf("%d",&x);
        int sum=0;
        for(int i=has[x]+x;i<N&&sum<x;i+=x){
            has[x]=i;
            if(!vis[i]){
                sum++,cnt++,vis[i]=1;
                if(lucky[i]){
                    lucky[i]=0;
                    ans.push_back(cnt);
                }
            }
        }
        cnt+=x-sum;
    }
    printf("%d\n",ans.size());
    for(int i=0;i<ans.size();i++){
        printf("%lld\n",ans[i]);
    }
		return 0;
}

(3)会员超市

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e3+5;
int q,n,m,p[N],f[N][N],dp[N];
vector<pair<int,int>>v[N];
int main() {
    cin>>q>>n>>m;
    for(int i=1;i<=n;i++){
        int w,vv,t;
        cin>>w>>vv>>t;
        v[t].push_back(make_pair(w,vv));
    }
    for(int i=1;i<=m;i++)  cin>>p[i];
    for(int k=1;k<=m;k++){
        if(v[k].size()==0) continue;
        for(int i=0;i<v[k].size();i++){
            int w=v[k][i].first,c=v[k][i].second;
            for(int j=q;j>=w;j--){
                f[k][j]=max(f[k][j],f[k][j-w]+c);
            }
        }
    }
  for(int k=1;k<=m;k++){
      if(v[k].size()==0) continue;
      for(int j=q;j>=p[k];j--){
          for(int i=1;i<=q;i++){
              if(i+p[k]>j) break;
              dp[j]=max(dp[j],dp[j-p[k]-i]+f[k][i]);
          }
      }
  }
  cout<<dp[q];
			return 0;
}

(4)规则排序

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+5;
int n;
struct node{
	int a,b;
}c[N];
bool cmp(node x,node y){
	if(x.a==y.a) return x.b<y.b;
	return x.a<y.a;
}
int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
    	cin>>c[i].a>>c[i].b;
	}
	sort(c+1,c+n+1,cmp);
	for(int i=1;i<=n;i++){
		cout<<c[i].a<<" "<<c[i].b<<"\n";
	}
			return 0;
}

数论&思维:

(1)最小LCM

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+5;
ll a,b,k,minn;
ll gcd(ll a,ll b){
    if(!b)  return a;
    return gcd(b,a%b);
}
void check(ll x){
    ll tmpk;
    if(b%x==0)  tmpk=0;
    else tmpk=(b/x+1)*x-b;
    ll lcm=(a+tmpk)*(b+tmpk)/gcd(a+tmpk,b+tmpk);
    if(lcm<minn)  minn=lcm,k=tmpk;
    else if(lcm==minn)  k=min(k,tmpk);
}
int main(){
    scanf("%lld%lld",&a,&b);
    if(a<b)  swap(a,b);
    minn=a*b,k=0;
    ll tmp=a-b;
    for(ll i=1;i*i<=tmp;i++){
        if(tmp%i==0){
            check(i),check(tmp/i);
        }
    }
    cout<<k;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值