Codeforces Round #747 (Div. 2) (21.10.9)
Posted 未定_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #747 (Div. 2) (21.10.9)相关的知识,希望对你有一定的参考价值。
B. Special Numbers
题意: 给你n和k,进行幂运算,n为幂底数,将n的所有幂以及不同幂之和按顺序排列,找到第k个数。
如:n=3,k=4,序列为{1,3,4,9},表示30,31,30+31,32。
分析: 比赛的时候不会做,自己想的很复杂。
以下都是废话,直接从黑体字开始看。
以n=2,k=12为例。序列幂的指数排序如下:
0 个数为1
1 01 个数为2
2 02 12 012 个数为4
3 03 13 013 23 023 123 0123 个数为8
4 04 14 014 24 024 124 0124 34 034 134 0134 234 0234 1234 01234 个数为16
…
序列为:
1
2 3
4 5 6 7
8 9 10 12 11 13 14 15
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
…
第12个数为22+23=4+8=12
找规律发现每一行的个数为2的次方,所以我先根据k找到该数在第几行(为了和幂的次方对应,假设有第0行),int m=int(log(k)/log(2)),2m为该行数的个数。然后计算k为该行的第几个数,先计算sum=20+…+2m-1,然后int t=k-sum,t为m行的第几个数,本例m=3,t=12-7=5。
然后就卡住了。。。
分析了一大堆,觉得该用二进制操作。。。
以n=2,k=12为例,我们考虑12的二进制数1100,
发现结果恰好为1 * 23+1 * 22+0 * 21+0 * 20=8+4=12,从上面的列举也能发现指数的排序为23;
以n=3,k=4为例,4的二进制数为100,结果就为1 * 32+0 * 31+0 *3 0= 9。
怎么想到的?因为不论n取什么值,指数的排列是固定的,对应的k的位置也是固定的,从上面两个表中找对应关系,发现当n取2时,序列恰好是自然数排列,那么我们找k时,无论n取什么,一定都与n=2时的k在同一个位置,自然也就对应了指数的序列。比如:k=12,n=2时指数序列为2 3,也就是二进制中1100,1代表的数。
#include<bits/stdc++.h>
using namespace std;
int mod=1e9+7;
int main()
{
int t,n,k,ans,now;
cin>>t;
while(t--)
{
cin>>n>>k;
ans=0,now=1;
while(k)
{
if(k&1)//二进制取末尾
ans=(ans+now)%mod;
now=1ll*now*n%mod;//1ll表示把int转换成long long型
k>>=1;
}
cout<<ans<<endl;
}
}
C. Make Them Equal
题意:给你一个字符串s和字符c,每次操作可以选一个x(1<=x<=n),字符串不能整除x的位置上的字符替换成c,问操作几次可以使s的每一位全变成c。
分析:一开始情况没考虑全面,想的是从字符串的第2位到第n-1位找,如果有一个字符不是c,x1就等于n,然后判断第n位,如果不是c,x2就等于n-1,一共两步;如果字符串第二位到第n-1位都等于c,此时,如果第一位或第n位不是c,x1直接等于n-1即可。要么一步要么两步。
但这样写两步的时候没有考虑到2~n-1中存在一个m,且n<2*m,当2到n-1中存在一位(非m)不等于c,只需一步,x1=m。举个例子,5 b,babaa,我一开始的结果是2 5 4,实际上应该是1 3。
赛后重新修改代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t,n;
cin>>t;
char c,s[300010];
int cc[5];
while(t--)
{
cin>>n>>c>>(s+1);
int sum=0,p=0;
for(int i=n-1; i>=2; i--)
{
if(s[i]!=c)
{
sum++;
cc[p++]=n;
break;
}
}
if(sum)
{
if(s[n]!=c)
{
sum++;
cc[p++]=n-1;
}
}
else
{
if(s[1]!=c||s[n]!=c)
{
sum++;
cc[p++]=n-1;
}
}
if(sum==2)
{
for(int i=round((n+1)*1.0/2);i<=n-1;i++)
{
if(s[i]==c)
{
sum=1;
p=1;
cc[0]=i;
break;
}
}
}
cout<<sum<<endl;
for(int i=0; i<p; i++)
cout<<cc[i]<<" ";
cout<<endl;
}
}
以上是关于Codeforces Round #747 (Div. 2) (21.10.9)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #747 (Div. 2)B. Special Numbers
Codeforces Round #747 (Div. 2)B. Special Numbers
A. Consecutive Sum Riddle( Codeforces Round #747 (Div. 2))
Codeforces Round #747 (Div. 2) D题