A. Legs
题意:鸡兔同笼问题
思路:略,代码如下:
void solve(){
int n;
cin >> n;
int ans = 0;
ans += n/4;
ans += (n%4)/2;
cout << ans << endl;
}
B. Scale
题意:给定一个n*n的序列,给定一个数k,将该n*n的序列按顺序分割成若干个k*k个序列。
思路:间隔k个输出即可,代码如下:
void solve(){
int n,k;
cin >> n >> k;
vector<string>map(n+1);
for(int i = 0;i<n;i++){
cin >> map[i];
}
for(int i = 0;i<n;i+=k){
for(int j = 0;j<n;j+=k){
cout << map[i][j] ;
}
cout << endl;
}
}
C. Sort
题意:给定均为小写字母的字符串a和b,给定q个询问,每次询问给定l和r(左右区间),现在可以对该区间进行若干次操作,每次操作可以将区间内任意一个元素变为任意你想要的字母。求最终满足sorted(a[l..r])=sorted(b[l..r])的情况下,需要操作多少次。
思路:理解题意,区间内符合该要求的最少操作次数其实就是区间内不同的字母的个数,所以只需要统计区间内各个字母的个数即可,暴力会超时,这里用前缀和,统计26个字母的前缀个数和即可,代码如下:
void solve(){
int n,q;
cin >> n >> q;
int cnt_a[200005][27];
int cnt_b[200005][27];
for(int i = 1;i<=n;i++){
char a;
cin >> a;
for(int k = 1;k<=26;k++){
if(k == a-'a'+1){
cnt_a[i][k]=cnt_a[i-1][k]+1;
}else{
cnt_a[i][k]=cnt_a[i-1][k];
}
}
}
for(int i = 1;i<=n;i++){
char b;
cin >> b;
for(int k = 1;k<=26;k++){
if(k == b-'a'+1){
cnt_b[i][k]=cnt_b[i-1][k]+1;
}else{
cnt_b[i][k]=cnt_b[i-1][k];
}
}
}
for(int i = 1;i<=q;i++){
int l,r;
cin >> l >> r;
int same = 0;
for(int k = 1;k<=26;k++){
same += min(cnt_a[r][k]-cnt_a[l-1][k],cnt_b[r][k]-cnt_b[l-1][k]);
}
cout << (r-l+1-same) << endl;
}
}
D. Fun
题意:给定一个n和x求a,b,c满足a+b+c<=x 并且 a*b + b*c + a*c<=n的解的个数。
思路:枚举a和b,然后对c进行二分查找,找到最大的满足a+b+c<=x并且a*b+b*c+a*c<=n的解的个数,另ans初始为0,每次加上该二分查找结果最大的c,就是该次枚举的a和b和c的解的数量(注意这样做时间复杂度为O(n*n*logn)会超时,所以这里需要对b的枚举进行剪枝,当a和b乘积大于n说明c无论如何都不存在了,那么直接break取消循环)。代码如下:
void solve(){
int n,x;
cin >> n >> x;
int ans = 0;
for(int a = 1;a<=x;a++){
for(int b = 1;b+a<=x-1;b++){
if(a*b>n)break;
int l = 0,r = x-a-b+1;
while(l+1 != r){
int c = (l+r)>>1;
if(a*b+b*c+a*c <=n){
l = c;
}else{
r = c;
}
}
ans += l;
}
}
cout << ans << endl;
}