2020年10月28日普级组

题号标题
AMSWORLD
BSMRTFUN
C区间和的和
D最大异域和
E小B浇花
FPOPULAR

A:

题目描述

Bessie , Farmer John 的优选牛,刚刚获得了一个牛科动物选美比赛的冠军!并得到了“世界奶牛小姐”的头衔。因此,Bessie将进行一场环球农场旅行,共N个农场(2<=N<=50,000),依次传播农场主和奶牛们之间的亲善友好。为了简单起见,世界可以看作一个二维平面,每座农场的位置用二维坐标(x,y)表示,x,y是-10,0000到10,0000的整数。没有两座农场处于同一个位置上。

哪怕Bessie在两个农场间都是走的直线,在某些农场间的距离还是很远,所以她想随身携带一只装满了干草的箱子,这样她在每一段行程都有充足的食物。因为Bessie在她每到达一个农场后都要重新装满她的箱子,她想弄清楚她可能要走的最大距离,以此来决定它必须携带多大的箱子。帮帮Bessie吧!你只要求出任意两点距离的最大值就可以了。

输入

第一行,一个整数,N。第2~N+1行,两个整数X,Y,描述了农场的坐标。

输出

一个整数,最大距离的平方。

正题:

这题数据水,直接爆力
(负一的情况坑死人……)

#include<iostream>
#include<cstdio>
#include<algorithm> 
using namespace std;
long long n, ans=-1;
struct node
{
	long long x, y;
}a[100100];
long long dis(register long long x, register long long y, register long long x1, register long long y1)
{
	return (x-x1)*(x-x1)+(y-y1)*(y-y1);
}
int main()
{
	scanf("%lld", &n);
	for(register long long i=1; i<=n; i++)
	{
		scanf("%lld%lld", &a[i].x, &a[i].y);
		for(register long long j=1; j<i; j++)
			ans=max(ans,dis(a[i].x,a[i].y,a[j].x,a[j].y));
	}
	printf("%lld", ans);
	return 0;
}

B:

题目描述

“又肥又温顺,又大又笨,他们看起来那么傻,而且也不有趣……”

这些牛想要证明,他们是既有趣,又聪明的。为了这样做,Bessie组织了一个由牛组成的展览。她有N(1<=N<=100)头牛的情况:聪明程度Si(-1000<=Si<=1000)和有趣程度Fi(-1000<=Fi<=1000)。

Bessie必须选择一些牛来参展。牛的总的聪明值TS是所有参展牛的聪明值Si的和,总的有趣值TF是所有参展牛的有趣值Fi的和。Bessie希望能使TS和TF的和最大。但是,她仍然要求TF和TS都大于等于0,因为,如果其中一个小于0的话,对这个展出将是致命的。

所以,请帮助Bessie找到最大的TS和TF的和,而且这两个数都要非负。

输入

第一行,一个整数N,牛的个数。第2~N+1行,两个整数,依次是Si和Fi。

输出

仅一行,所求得的TS和TF的和

正题:

我们把 s i s_i si看成体积,然后就变成了一个01背包
这时直接01背包判断不了负数的状况,所以我们为状态加上一个400000(洛谷数据),最后判断最大的时候减去就可以了

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n, ans;
int s[100100], f[100100];
int dp[10001000]; 
int main()
{
	scanf("%d", &n);
	for(int i=1; i<=n; i++)
		scanf("%d%d", &s[i], &f[i]);
	memset(dp, -0x3f, sizeof(dp));
	dp[400000]=0;
	for(int i=1; i<=n; i++)
	{
		if(s[i]>=0)
		{
			for(int j=800000; j>=s[i]; j--)
				dp[j]=max(dp[j], dp[j-s[i]]+f[i]);
		}
		else
		{
			for(int j=0; j<=800000+s[i]; j++)
				dp[j]=max(dp[j], dp[j-s[i]]+f[i]);
		}
	}
	int ans=0;
	for(int i=400000; i<=800000; i++)
		if(dp[i]>=0)
			ans=max(ans, dp[i]+i-400000);
	printf("%d", ans);
	return 0;
} 

C:

在这里插入图片描述

正题:

这题我们考虑第i个数被加了几次
第1个数会被加1n次
第2个数会被加2
(n-1)次
第3个数会被加3*(n-2)次
……
第n个数会被加n*1次

#include<iostream>
#include<cstdio>
using namespace std;
long long n;
long long a[1001000];
int main()
{
	scanf("%lld", &n);
	for(long long i=1; i<=n; i++)
	{
		scanf("%lld", &a[i]);
		a[i]=a[i]%1000000007;
	}
	long long j=1;
	long long ans=0;
	for(long long i=n; i>=1; i--)
	{
		long long sum=j*i%1000000007;
		sum=sum*a[i]%1000000007;
		ans=(ans+sum)%1000000007;
		j++;
	}
	printf("%lld", ans);
	return 0;
}

D:

在这里插入图片描述

正题:

因为异或最大只能是第一个比当前数列最大值大的二进制位上全是1的个数,所以就把2的次幂数算出来,最后做个比较

#include<iostream>
#include<cstdio>
using namespace std;
int n;
int a[1010];
int b[1010];
int main()
{
	a[0]=1;
	for(int i=1; i<=31; i++)
		a[i]=a[i-1]*2;
	scanf("%d", &n);
	int maxx=0;
	for(int i=1; i<=n; i++)
	{
		int x;
		scanf("%d", &b[i]);
		maxx=max(maxx, b[i]);
	}
	for(int i=1; i<=31; i++)
		if(a[i]>maxx)
		{
			maxx=a[i];
			break;
		}
	int sum=0;
	for(int i=1; i<=n; i++)
		sum+=b[i];
	if(sum>=maxx)
		printf("%d", maxx-1);
	else
		printf("%d", sum);
	return 0;
} 

E:

在这里插入图片描述

正题:

我们用一个桶累计当前高度的树,从0~39999直接把每一位都变成1,到40000的时候就直接用等差数列求和公式求出来

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
int a[101000];
int main()
{
	scanf("%d", &n);
	for(int i=1; i<=n; i++)
	{
		int x;
		scanf("%d", &x);
		a[x]++;
	}
	long long ans=0;
	for(int i=0; i<=39999; i++)
	{
		if(a[i]!=0)
		{
			ans+=a[i]-1;
			a[i+1]+=a[i]-1;
			a[i]=1;
		}
	}
	if(a[40000]!=0)
		ans+=a[40000]*(a[40000]-1)/2;
	printf("%lld", ans);
	return 0;
}

F:

题目描述

每头牛都有一个梦想:成为一个群体中最受欢迎的名牛!在一个有N(1<=N<=10,000)头牛的牛群中,给你M(1<=M<=50,000)个二元组(A,B),表示A认为B是受欢迎的。既然受欢迎是可传递的,那么如果A认为B受欢迎,B又认为C受欢迎,则A也会认为C是受欢迎的,哪怕这不是十分明确的规定。你的任务是计算被所有其它的牛都喜欢的牛的个数。

输入

第一行,两个数,N和M。第2~M+1行,每行两个数,A和B,表示A认为B是受欢迎的。

输出

一个数,被其他所有奶牛认为受欢迎的奶牛头数。

正题:

爆搜一遍直接AC,但在洛谷上要用缩点+Tarjia

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n, m, tot, head[100100], t[100100];
struct node{
	int to, next;
}b[1001000];
bool v[10001];
void add(int x, int y)
{
	b[++tot]=(node){y, head[x]};
	head[x]=tot;
}
void dfs(int x)
{
	v[x]=1;
	for(int i=head[x]; i; i=b[i].next)
	{
		int y=b[i].to;
		if(v[y]==1)
			continue;
		t[y]++;
		dfs(y);
	}
}
int main()
{
	scanf("%d%d", &n, &m);
	for(int i=1; i<=m; i++)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		add(x, y);
	}
	for(int i=1; i<=n; i++)
	{
		memset(v, 0, sizeof(v));
		dfs(i);
	}
	int ans=0;
	for(int i=1; i<=n; i++)
		if(t[i]==n-1)
			ans++;
	printf("%d", ans);
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值