题号 | 标题 |
---|---|
A | MSWORLD |
B | SMRTFUN |
C | 区间和的和 |
D | 最大异域和 |
E | 小B浇花 |
F | POPULAR |
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;
}