A: 简单策略
B: 简单数学
C: 也算数学吧
D 还是数学吧+简单模拟,感觉难度比C低。
今晚这场个人感觉难度比较低一点(前四题)
A
题意:
问:是否存在a的一个子串p, 使得pi=I;
解:只需存在一个i,满足ai<=i即可
- void solve()
- {
- int n;
- cin>>n;
- for(int i=1;i<=n;i++)
- cin>>a[i];
- bool prime=false;
- for(int i=1;i<=n;i++)
- if(a[i]<=n&&i>=a[i])
- prime=true;
- if(prime)
- cout<<"YES"<<endl;
- else
- cout<<"NO"<<endl;
- }
B:
题意:
对于每个数,可以进行如下操作:
1: x=x*2-1
2: x=x*2+1
初始手上有一个数为1,问是否可以对其操作不大于40次得到一个给定的数n
若可以,输出给定的操作序列。
解:将数看成二进制的表达,
1操作就是整体左移1,将最低位的1改为0同时将后面的数置为1
2 操作就是整体左移1,最后一位的0 加上1;
手动模拟发现:
1 -> 11 or 1
11 -> 111 or 101
111 -> 1111 or 1101
101 -> 1011 or 1001
很容易发现规律以及构造方案。
将给定的n分解为2进制表达,若最低位不为1 则无解
否则先将1 进行2操作,然后观察 观察n除了最高位以外的当前位置,为1进行2操作,为0进行1操作
- void solve()
- {
- int n;
- cin>>n;
- vector<int> v;
- while(n)
- {
- v.push_back(n%2);
- n>>=1;
- }
- int num=v.size();
- if(v[0]!=1)
- cout<<-1<<endl;
- else
- {
- cout<<num-1<<endl;
- cout<<2<<" ";
- for(int i=1;i<=num-2;i++)
- if(v[num-1-i]==1)
- cout<<2<<" ";
- else
- cout<<1<<" ";
- cout<<endl;
- }
- }
C:
给定数组n
操作1 删除任意位置一个数,代价c
操作2 在任意位置插入任意一个数,代价d
问,将数组n转化成一个长度为p(p>0)的排列,最小代价是多少
解:
先将数组去重,删除重复元素的代价是一定要付出的。
Sort
特判: 将数组转化为1的排列 所需的代价
有点递推的影子,
将数组构造成长度为a[i]所需的代价,为构造成a[i-1]所需的代价+ 补上中间缺少的数的代价 + ( -d , (构造成a[i-1]的代价比构造成a[i]的代价多删除了 一个数a[i] ) )
Res取min (细节处还需处理)
D
题意:
蜗牛爬树,树高h米(未知),白天爬a米,晚上休息掉落b米,(a>b),需要爬行n天
q个操作,
1操作: 给定,a,b,n,若不与先前条件矛盾,则将其添加到限制条件里面。否则无视
2操作: 给定a,b; 问要爬几天; 如果不确定输出-1,如果确定则输出对应天数
解:
未知树高,设树高的范围为[hl,hr]
对于a,b,n; 由数学关系分析可知:
If n==1
则 hr<=a
Else
n*a-(n-1)*b>=hr
hl>(n-1)*a-(n-2)*b
对于1操作,若由当前abn确定的l r范围不涵盖在之前的范围里面,则矛盾
涵盖在之前的范围里面的话,则缩小范围
- if(op==1)
- {
- int a,b,n;
- cin>>a>>b>>n;
- bool prime=true;
- if(n==1)
- {
- ll h2=a;
- if(h2<hl)
- prime=false;
- else
- hr=min(hr,h2);
- }
- else
- {
- ll h1=(ll)(n-1)*a-(ll)(n-2)*b+1;
- ll h2=(ll)n*a-(ll)(n-1)*b;
- if(h2<hl||h1>hr)
- prime=false;
- else
- {
- hr=min(hr,h2);
- hl=max(hl,h1);
- }
- }
- if(prime)
- cout<<1<<" ";
- else
- cout<<0<<" ";
- }
对于2操作,可定量计算,分析天数是否为1即可
- else
- {
- int a,b;
- cin>>a>>b;
- ll res=-1;
- if(hr<=a) //一天内可以爬完
- res=1;
- else
- {
- //分别计算左右边界所需要的天数
- ll n1=(hr-b+a-b-1)/(a-b);
- ll n2=(hl-b+a-b-1)/(a-b);
- if(n1==n2)
- res=n1;
- }
- cout<<res<<" ";
- }