普及模拟测试1#解题报告

T1:

简单模拟,注意初始化。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,ans;char a[100000],b[100000],s[10005];
int main() {
	scanf("%d",&n);
	scanf("%s",a+1);
	scanf("%s",b+1);
	scanf("%d",&m);
	int l,r,c;
	for(int i=1; i<=m; i++) {
		scanf("%d%d%d",&l,&r,&c);
		if(l>r)swap(l,r);
		for(int j=l; j<=r; j++) {
		    int k=j-l+1+c;
		    k=k%(r-l+1);//显而易见的公式。。。
		    if(k==0)s[r]=a[j];
		    s[l-1+k]=a[j];
		}
		for(int j=l; j<=r; j++) {
			a[j]=s[j];
		}
		memset(s,0,sizeof(s));
	}
	for(int i=1; i<=n; i++) {
		if(a[i]==b[i])ans++;
	}
	cout<<ans;
}

没多少好说的。。。。

T2:

额,思路是贪心,就是每次都算一下在当前的最大高度保留时拆的符合条件的最小费用再与答案比较。但如果只是一开始按费用排完序然后每次都从低费用的开始取比最大高度矮的显然会TLE,所以考虑从上一个最大高度的费用稍做修改,将拆掉的高度比现在高的加回来,再取其他的。这样就需要一个优先队列来维护高度。

比较懒。。。。。待会再回来填坑。。。。。

T3:

又是贪心。。。。

明显每次都用除草机来除面积最大的是最优的,这样其他的每次就减一个单位的就好了,又是开个优先队列,取队头即最大的那个用除草机。其他减一的就当做所有一起减只有用除草机的加一,到判是否出队时与时间做比较,减了时间次一,小于时间直接出队。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue> 
using namespace std;
int n,m,tot=0,a,ans=0;;
priority_queue<int> q;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a);
        if(a!=0)q.push(a);
    }
    while(!q.empty()){
    int k=q.top();q.pop();
    if(k<ans)break;  
    else ans++;
    q.push(max(k-m+1,0));
    }
    cout<<ans;
}  


T4:

动归,

转移

(1)只有第i只猴子爬到第j棵树上

(2)除了第i只猴子外还有别的猴子爬到第j棵树上

f[i][j]=min{f[i-1][j-1],f[i-1][j]}+abs(a[i]-b[j])

时间复杂度为O(n^2)

特别注意要有滚动数组,否则会超空间、

#include <iostream>
using namespace std;
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
const int N=5005;
int n,m;
int x[N],y[N];
long long f[2][N];
int main(){
    int i,j;
    scanf("%d",&n);for(i=1;i<=n;i++) scanf("%d",&x[i]);
    scanf("%d",&m);for(i=1;i<=m;i++) scanf("%d",&y[i]);;
    sort(x+1,x+n+1);//排序
    sort(y+1,y+m+1);//排序
    memset(f,0x7f,sizeof(f));
    f[1][1]=abs(x[1]-y[1]);
    for(i=2;i<=n;i++)
        for(j=1;j<=m;j++)
            f[i&1][j]=min(f[i-1&1][j-1],f[i-1&1][j])+(long long)abs(x[i]-y[j]);
    cout<<f[n&1][m]<<endl;
    return 0;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值