场次链接
A、Cow and Haybales
题目链接
给n堆草,可以进行d次操作,每次操作可以将移动一根草到相邻的堆,问第一堆最多可以有几根草。
数据范围
1
≤
t
≤
100
1\leq t\leq 100
1≤t≤100,
1
≤
n
,
d
≤
100
1\leq n,d\leq 100
1≤n,d≤100,
1
≤
a
i
≤
100
1\leq a_i\leq 100
1≤ai≤100
解 从左往右将对应位置的草移到第一堆即可。
复杂度
O
(
n
)
O(n)
O(n)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[105];
void work()
{
int n,d;
scanf("%d%d",&n,&d);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int ans=a[1];
for(int i=2;i<=n;i++){
int tmp=(i-1)*a[i];
if(tmp<=d){
ans+=a[i];
d-=tmp;
}else{
ans+=d/(i-1);
break;
}
}
printf("%d\n",ans);
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T=1;
scanf("%d",&T);
//cin>>T;
while(T--){
work();
}
}
B、Cow and Friend
题目链接
要从(0,0)移动到(x,0),每次移动的欧几里得距离必须为n个
a
i
a_i
ai中的一个,问最少要移动几次。
数据范围
1
≤
t
≤
1000
1\leq t\leq 1000
1≤t≤1000,
1
≤
n
≤
1
0
5
1\leq n\leq 10^5
1≤n≤105,
1
≤
x
≤
1
0
9
1\leq x\leq 10^9
1≤x≤109,
1
≤
a
i
≤
1
0
9
1\leq a_i\leq 10^9
1≤ai≤109
解 sort一下a数组,然后看能否一步走到,即x是否在
a
i
a_i
ai中,否则就是所有步数都使用
a
n
a_n
an为最优,计算需要几步即可
复杂度
O
(
n
)
O(n)
O(n)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[100005];
void work()
{
int n,x;
scanf("%d%d",&n,&x);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
sort(a+1,a+n+1);
if(x<=a[n]){
for(int i=1;i<=n;i++){
if(a[i]==x){
printf("1\n");
return;
}
}
printf("2\n");return;
}
if(x%a[n]==0){
printf("%lld\n",x/a[n]);
}else{
printf("%lld\n",x/a[n]+1);
}
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T=1;
scanf("%d",&T);
//cin>>T;
while(T--){
work();
}
}
C、Cow and Message
题目链接
给一个字符串,你可以取出其中的子序列,但要求取出的子序列字母之间的距离相等,即
1
,
3
,
5
1,3,5
1,3,5或者是
2
,
3
,
4
2,3,4
2,3,4,不能是
1
,
2
,
4
1,2,4
1,2,4这种,问最多能取出多少个相同的子序列。
数据范围
1
≤
∣
s
∣
≤
1
0
5
1\leq |s|\leq 10^5
1≤∣s∣≤105
解 如果只取长度为2的子序列,相当于没有距离的条件限制,如果扩大到长度为3,那么显然长度为2的子序列是长度为3的子序列的前缀,而第3个字母是不同的,所以答案的长度只有1个字母或者2个字母,枚举26*26即可。
复杂度
O
(
∣
s
∣
)
O(|s|)
O(∣s∣)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
char a[100005];
ll b[26];
void work()
{
scanf("%s",a);
int l=strlen(a);
for(int i=0;i<l;i++){
b[a[i]-'a']++;
}
ll maxx=0;
for(int i=0;i<26;i++){
maxx=max(maxx,b[i]);
}
ll ans=max(maxx*(maxx-1)/2,maxx);
for(int i=0;i<26;i++){
for(int j=0;j<26;j++){
if(i==j)continue;
int cnt=0;
ll tmp=0;
for(int k=0;k<l;k++){
if(a[k]==i+'a')cnt++;
if(a[k]==j+'a'){
tmp+=cnt;
}
}
ans=max(ans,tmp);
}
}
printf("%lld\n",ans);
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T=1;
//scanf("%d",&T);
//cin>>T;
while(T--){
work();
}
}
D、Cow and Fields
题目链接
给n个点m条边,然后再k个特殊点,你可以在这k个特殊点中的2个点加一条边,问你加完边之后从1到n的最短路的最大值。
数据范围
2
≤
n
≤
2
∗
1
0
5
2\leq n\leq 2*10^5
2≤n≤2∗105,
n
−
1
≤
m
≤
2
∗
1
0
5
n-1\leq m\leq 2*10^5
n−1≤m≤2∗105,
2
≤
k
≤
n
2\leq k\leq n
2≤k≤n,
1
≤
a
i
≤
n
1\leq a_i\leq n
1≤ai≤n,
1
≤
x
i
,
y
i
≤
n
1\leq x_i,y_i\leq n
1≤xi,yi≤n
解 如果加完边之后使得最短路变短 那么肯定通过了这条边 所以2次bfs处理出所有点到1和n的距离,然后将a数组根据到1的距离排序(我用的set,差别不大),然后尝试从
a
i
−
1
a_{i-1}
ai−1向
a
i
a_i
ai连边,然后求走这条路的距离,然后再求个最大值,再和1-n距离取最小。
复杂度
O
(
n
+
k
l
o
g
k
)
O(n+klogk)
O(n+klogk)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
int x;
int d;
};
int a[200005];
vector<int>v[200005];
int d[200005];
int l[200005];
int vis[200005];
int mmm[200005];
bool f=false;
int n,m,k;
void bfs1()
{
node now;
now.x=1;
now.d=0;
queue<node>q;
q.push(now);
while(!q.empty()){
now=q.front();
q.pop();
//printf("%d %d\n",now.x,now.d);
for(int i=0;i<v[now.x].size();i++){
if(v[now.x][i]!=1&&d[v[now.x][i]]==0){
d[v[now.x][i]]=now.d+1;
node nxt;
nxt.x=v[now.x][i];
nxt.d=now.d+1;
q.push(nxt);
}
}
}
}
void bfs2()
{
node now;
now.x=n;
now.d=0;
queue<node>q;
q.push(now);
while(!q.empty()){
now=q.front();
q.pop();
for(int i=0;i<v[now.x].size();i++){
if(v[now.x][i]!=n&&l[v[now.x][i]]==0){
l[v[now.x][i]]=now.d+1;
node nxt;
nxt.x=v[now.x][i];
nxt.d=now.d+1;
q.push(nxt);
}
}
}
}
void work()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
bfs1();
bfs2();
set<int>s1;
for(int i=1;i<=k;i++){
if(s1.find(d[a[i]])==s1.end()){
s1.insert(d[a[i]]);
}else{
printf("%d\n",d[n]);return;
}
}
for(int i=1;i<=k;i++){
mmm[d[a[i]]]=a[i];
}
set<int>::iterator it1;
set<int>::iterator it2;
int ans=0;
it1=it2=s1.begin();
it2++;
for(;it2!=s1.end();it1++,it2++){
int tmp=min(*it1+1+l[mmm[*it2]],*it2+1+l[mmm[*it1]]);
if(tmp>d[n]){
printf("%d\n",d[n]);return;
}else{
ans=max(ans,tmp);
}
}
printf("%d\n",ans);
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T=1;
//scanf("%d",&T);
//cin>>T;
while(T--){
work();
}
}