cf edu31

cf edu31

A

题目要求

给出需要读书的总时间 以及每天剩余的时间 问多少天能读完

参考AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<bits/stdc++.h>
using namespace std;
int main(){
// freopen("input.txt","r",stdin);
int n,t,i;
scanf("%d%d",&n,&t);
for(i=1;i<=n;i++){
int x;
scanf("%d",&x);
int free=86400-x;
t-=free;
if(t<=0) break;
}
printf("%d\n",i);
return 0;
}

思路

直接模拟

B

题目要求

定义一串字符的encode为多个连续1的个数
给出encode的数字和解码前的大小n 问能否存在一种解码前的数字使得解码后是给出的数字

参考AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<bits/stdc++.h>
using namespace std;
int main(){
// freopen("input.txt","r",stdin);
int n,len;
scanf("%d%d",&n,&len);
int sum=0;
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
if(i==1) sum+=x;
else sum+=1+x;
}
if(sum==len) puts("YES");
else puts("NO");
return 0;
}

思路

直接模拟

C

题目要求

有n个车站(车站编号为1~n) 满足Bertown Transport Law:
1.对于每个车站i 一定有目的地车站pi(允许pi=i)
2.对于每个车站i 存在唯一的pj=i
舒适度是有序数对(x, y)的数量 使得从车站x出发能够到达车站y(允许x=y)
总统即将来访 市长想要提升舒适度 便试图改造线路
他能够改变某些车站的pi值 但他最多调整两个 且调整后的车站仍满足Bertown Transport Law 求最大舒适度

参考AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<bits/stdc++.h>
#define maxn 100050
#define mm(a,b) memset(a,b,sizeof(a))
#define LL long long
using namespace std;
int n;
int p[maxn],vis[maxn];
int main(){
// freopen("input.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&p[i]);
mm(vis,0);
LL max1=0,max2=0;
LL ans=0;
for(int i=1;i<=n;i++){
if(vis[i]) continue;
LL cnt=1;
vis[i]=1;
int x=p[i];
while(x!=i){
cnt++;
vis[x]=1;
x=p[x];
}
ans+=cnt*cnt;
if(cnt>=max1){
max2=max1;
max1=cnt;
}
else if(cnt>max2 && cnt<max1) max2=cnt;
}
ans+=2LL*max1*max2;
printf("%lld\n",ans);
return 0;
}

思路

可以看出每次操作会最多会改变2个环 假设原本环分别为a和b
那么合并后(a+b)²-(a²+b²)=2ab
所以我们只要找到最大的2个环把她们合并起来即可 对结果合并的影响就是增加2ab

D

题目要求

有n种颜色的球和n个箱子 每种颜色的球有ai个 一开始所有球都在第一个箱子里
最后要满足的状态为:箱子i里包含所有颜色为i的球 问消耗的最小总代价
可以进行如下操作:
每次从一个非空箱子中取出所有球 代价为球的数量 把他们分成2(3)份放到2(3)个非空箱子中

参考AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n;
priority_queue<ll,vector<ll>,greater<ll> >Q;
int main(){
// freopen("input.txt","r",stdin);
ll res=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
Q.push(x);
}
if(n%2==0) Q.push(0);
while(Q.size()>1){
ll t1=Q.top();
Q.pop();
ll t2=Q.top();
Q.pop();
ll t3=Q.top();
Q.pop();
res+=t1+t2+t3;
Q.push(t1+t2+t3);
}
printf("%lld\n",res);
return 0;
}

思路

类似于哈夫曼树
贪心可以发现 排序后要使小的数字尽量多的来回取出
由于这里的k=2/3 相当于一个二叉+三叉哈夫曼树 为了简化 如果n是偶数 我们加一个0 不影响结果
每次取三个数字 代价为他们的颜色对应的数量和 直到合并成1个数字 输出结果

F

转跳链接

文章目录
  1. 1. cf edu31
    1. 1.1. A
      1. 1.1.1. 题目要求
      2. 1.1.2. 参考AC代码
      3. 1.1.3. 思路
    2. 1.2. B
      1. 1.2.1. 题目要求
      2. 1.2.2. 参考AC代码
      3. 1.2.3. 思路
    3. 1.3. C
      1. 1.3.1. 题目要求
      2. 1.3.2. 参考AC代码
      3. 1.3.3. 思路
    4. 1.4. D
      1. 1.4.1. 题目要求
      2. 1.4.2. 参考AC代码
      3. 1.4.3. 思路
    5. 1.5. F
|