cf round433

cf round433

A

题目要求

每个医生有开始上班的时间s和时间间隔d 即他在s s+d s+2d···天上班
现给出n个医生 必须按顺序(1-n)访问每个医生 问访问到最后一个医生时是多少天

参考AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<bits/stdc++.h>
#define maxn 100050
using namespace std;
int n;
int s[maxn],d[maxn];
int main(){
// freopen("input.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&s[i],&d[i]);
int cur=0;
for(int i=1;i<=n;i++){
if(s[i]>cur) cur=s[i];
else{
int j=(cur-s[i])/d[i];
cur=s[i]+d[i]*(j+1);
}
}
printf("%d\n",cur);
return 0;
}

思路

暴力模拟
题目关键是按顺序访问 cur记录天数 直接模拟每一个医生即可

B

题目要求

n个人比赛 每个人有一个能力值 能力值大的获胜
每次站在对头的人和后一个人比 赢的人继续在对头和下一个人比 输的人去队尾
现问第一个获得k场胜利的人的能力值是多少

参考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
36
37
38
39
40
41
42
43
44
45
46
47
48
#include<bits/stdc++.h>
#define maxn 550
#define LL long long
using namespace std;
struct node{
int power;
LL num;
node(int power,LL num):power(power),num(num){}
};
int a[maxn];
int n;
LL k;
deque<node>q;
int main(){
// freopen("input.txt","r",stdin);
scanf("%d%lld",&n,&k);
int Max=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
Max=max(Max,a[i]);
q.push_back(node(a[i],0));
}
if(k>=1000){
printf("%d\n",Max);
return 0;
}
int ans=0;
while(1){
node x=q.front();
q.pop_front();
if(x.num==k){
ans=x.power;
break;
}
node y=q.front();
q.pop_front();
if(x.power>y.power){
q.push_front(node(x.power,x.num+1));
q.push_back(node(y.power,y.num));
}
else if(x.power<y.power){
q.push_front(node(y.power,y.num+1));
q.push_back(node(x.power,x.num));
}
}
printf("%d\n",ans);
return 0;
}

思路

双端队列直接模拟
注意n最多只有500 所以经过500场之后能力值最大的人会一直站在对头 所以k大于500直接输出最大能力值即可

C

题目要求

有n次操作 形式是| & ^加上一个数字
现在要求简化结果 最多k行 形式和上面相同 要求最后得到的结果相同

参考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
36
37
#include<bits/stdc++.h>
using namespace std;
int n,op;
char s[10];
int main(){
// freopen("input.txt","r",stdin);
scanf("%d",&n);
int x=0,y=0x3ff;
for(int i=1;i<=n;i++){
scanf("%s %d",s,&op);
if(s[0]=='|'){
x|=op;
y|=op;
}
else if(s[0]=='&'){
x&=op;
y&=op;
}
else if(s[0]=='^'){
x^=op;
y^=op;
}
}
int or_num=0,and_num=0,xor_num=0;
for(int i=0;i<10;i++){
int bit=1<<i;
if(bit&x){
if(bit&y) or_num|=bit,and_num|=bit;
else xor_num|=bit,and_num|=bit;
}
else{
if(bit&y) and_num|=bit;
}
}
printf("3\n& %d\n| %d\n^ %d\n",and_num,or_num,xor_num);
return 0;
}

思路

最后结果肯定可以简化成三行 或一个数字 与一个数字 异或一个数字 分别记录每种操作对应的二进制数即可
最多只有四种情况
1.0->0,1->0,则f[i]=“&0,|0,^0”,即a[i]=0,b[i]=0,c[i]=0
2.0->0,1->1,则f[i]=“&1,|0,^0”,即a[i]=1,b[i]=0,c[i]=0
3.0->1,1->0,则f[i]=“&1,|0,^1”,即a[i]=1,b[i]=0,c[i]=1
4.0->1,1->1,则f[i]=“&1,|1,^0”,即a[i]=1,b[i]=1,c[i]=0
x和y分别记录三种操作对应的0是否变1 1是否变0
然后判断是四种情况里的哪一种

文章目录
  1. 1. cf round433
    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. 思路
|