2018.01.28【NOIP普及组】模拟赛D组

111 篇文章 0 订阅
27 篇文章 0 订阅

JZOJ NO.1 【usaco2013 mar】懒惰的奶牛[b]

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;
int n,k,g,x; long long ans,t[5000001];
int main(){
	freopen("lazy_bronze.in","r",stdin);
	freopen("lazy_bronze.out","w",stdout);
	scanf("%d%d",&n,&k);
	for (int i=1;i<=n;i++)
	 scanf("%d%d",&g,&x),t[x]=g;
	for (int i=1;i<=5000001;i++)
	 t[i]=t[i-1]+t[i]; 
	for (int i=5000001;i>=k*2;i--)
	 ans=max(ans,t[i]-t[i-(k*2+1)]); 
	printf("%lld",ans);
	return 0;
}

JZOJ NO.2 【usaco2013 mar】灌溉农田

题目分析:

求最小生成树(prim)


代码

#include <cstdio>
#include <algorithm>
using namespace std;
int o(int u){return u*u;}
int x[2001],y[2001],low[2001];bool v[2001];
int f[2001][2001],n,c,ans;
int main(){
	freopen("irrigation.in","r",stdin);
	freopen("irrigation.out","w",stdout);
	scanf("%d%d",&n,&c);
	for (int i=1;i<=n;i++){
		scanf("%d%d",&x[i],&y[i]);
		for (int j=1;j<=i-1;j++){
			int w=o(x[i]-x[j])+o(y[i]-y[j]);//代价
			if (w<c) w=2147483647;//小于c赋值最大值
			f[i][j]=f[j][i]=w;
		}
	} v[1]=1;
	for (int i=1;i<=n;i++) low[i]=f[1][i];//更新最小值
	for (int i=1;i<=n-1;i++){
		int minx=2147483647,k=0;
		for (int j=1;j<=n;j++)
		if (low[j]<minx&&!v[j]){
			minx=low[j];
			k=j;
		} v[k]=1; ans+=minx;
		if (minx==2147483647){printf("-1"); return 0;}
		for (int j=1;j<=n;j++)
		low[j]=min(low[j],f[k][j]);//更新最小值
	}
	printf("%d",ans);
	return 0;
}

JZOJ NO.3 【usaco2013 mar】懒惰的奶牛[s]

分析:

一开始肯定会想到 o ( n 4 ) o(n^4) on4,但是这样在 n &lt; = 400 n&lt;=400 n<=400的情况下无能为力,会超时,所以为了节省时间,运用前缀和,还有,就是少用algorithm的min and max 我就是因为这样超时了。


o ( n 3 ) o(n^3) on3

#include <cstdio>
using namespace std;
int ans,n,k,sum;
short a[401][401]; int s[401][401];
int abs(int y){return (y>0)?y:-y;}
int main(){
	freopen("lazy_silver.in","r",stdin);
	freopen("lazy_silver.out","w",stdout);
	scanf("%d%d",&n,&k);
	for (int i=1;i<=n;i++)
	for (int j=1;j<=n;j++)
	scanf("%d",&a[i][j]),s[i][j]=s[i][j-1]+a[i][j];
	for (int i=1;i<=n;i++)
	for (int j=1;j<=n;j++){
	sum=0; int u=i-k; if (u<1) u=1; 
	int v=i+k; if (v>n) v=n;
	for (int r=u;r<=v;r++){
	int t=abs(i-r); int q=j+k-t; if (q>n) q=n;
	int o=j-k+t; if (o<1) o=1;
	sum+=s[r][q]-s[r][o-1];
	}
	ans=(ans>sum)?ans:sum;
	}
	printf("%d",ans);
	return 0;
}

JZOJ NO.4 【usaco2013 mar】奶牛的声音

题目分析:

完全背包求方案数+纯模拟。


代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int f[200001],n,b,a[21],s1,ans,x;
int main(){
	freopen("mooomoo.in","r",stdin);
	freopen("mooomoo.out","w",stdout);
	memset(f,0x7f,sizeof(f));
	scanf("%d%d",&n,&b);
	for (int i=1;i<=b;i++) scanf("%d",&a[i]); f[0]=0;
	for (int i=1;i<=b;i++)
    for (int j=0;j<=100000;j++)
    f[j+a[i]]=min(f[j]+1,f[j+a[i]]);//完全背包求方案数
    for (int i=1;i<=n;i++){
        scanf("%d",&x);
        if (!x) continue;
        if (s1<=x&&f[x-s1]!=2139062143) ans+=f[x-s1];
        else if (s1<=x){printf("-1"); return 0;}//找不到方案。
        s1=x-1;//声音-1
	}
	printf("%d",ans); return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值