cf#469

链接:cf#469

C

题目大意

  • 给你一个01串,将他分成k个子串,每个子串由0开始0结尾,01交替出现

    题解

  • 两个数组分别存以0结尾,以1结尾的串的序号,当当前字符为1的时候,如果以0结尾的串为空,输出-1
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<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#define rep(i,x,y) for(register int i=x;i<=y;++i)
#define repd(i,x,y) for(register int i=x;i>=y;--i)
#define ll long long
using namespace std;
const int N=200010;
char s[N];
vector<int> ans[N],z1,z0;

int main(){
scanf("%s",s+1);
int len=strlen(s+1);
rep(i,1,len){
if(s[i]=='1'){
if(!z0.size()){
puts("-1");return 0;
}
int t=z0.back();z0.pop_back();
ans[t].push_back(i);z1.push_back(t);
}
else {
if(!z1.size()){
z0.push_back(i);ans[i].push_back(i);
}
else {
int t=z1.back();z1.pop_back();
ans[t].push_back(i);z0.push_back(t);
}
}
}
if(z1.size()){
puts("-1");return 0;
}
printf("%d\n",z0.size());
len=z0.size();
rep(i,0,len-1){
int tp=ans[z0[i]].size();
printf("%d",tp);
rep(j,0,tp-1)printf(" %d",ans[z0[i]][j]);
printf("\n");
}
return 0;
}

D

题目大意

  • n个数字,每两个数字中间插一个空,每次将最右边的数移动到最右边的空格处,q个询问,问最后在xi位置的元素

    题解

  • 数据范围是1e18次方,显然需要找规律,显然n/2左边的数字都是不动的,对于第x(i)个位置的元素,他会转移到2*(x(i)-n)的位置
  • 上去,即是P(x)=n+x/2 (x位置上的元素由P(x)转移过来)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define rep(i,x,y) for(register int i=x;i<=y;++i)
    #define repd(i,x,y) for(register int i=x;i>=y;--i)
    #define ll long long
    using namespace std;
    ll n,q,x;

    int main(){
    while(~scanf("%I64d%I64d",&n,&q)){
    while(q--){
    scanf("%I64d",&x);
    while(!(x&1))x+=n-x/2;
    printf("%I64d\n",(x+1)/2);
    }
    }
    return 0;
    }

总结

  • 考场上两道题都没做出来,没状态,code能力太弱。
  • 再弱小也还是要努力地活下去。