Educational Codeforces Round 145 Div. 2 题解

本文提供了四道编程题的详细解析,包括灯泡开关问题的最小操作次数、在平面上放置点的最小成本、构造特定子序列和以及二进制字符串排序的最小费用。每道题都涉及到不同的算法思路,如找规律、数学优化、贪心策略和动态规划。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

A. Garland(签到)

题面翻译

思路:

代码

B. Points on Plane(数学)

题面翻译

思路:

代码

C. Sum on Subarray(构造)

题面翻译:

思路:

代码

D. Binary String Sorting

题面翻译

思路:

代码


A. Garland(签到)

You have a garland consisting of 4 colored light bulbs, the color of the i-th light bulb is si.

Initially, all the light bulbs are turned off. Your task is to turn all the light bulbs on. You can perform the following operation any number of times: select a light bulb and switch its state (turn it on if it was off, and turn it off if it was on). The only restriction on the above operation is that you can apply the operation to a light bulb only if the previous operation was applied to a light bulb of a different color (the first operation can be applied to any light bulb).

Calculate the minimum number of operations to turn all the light bulbs on, or report that this is impossible.

Input

The first line contains a single integer t (1≤t≤104) — the number of test cases.

The single line of each test case contains s— a sequence of 4 characters, where each character is a decimal digit. The i-th character denotes the color of the i-th light bulb.

Output

For each test case, print one integer — the minimum number of operations to turn all the light bulbs on. If it is impossible to turn all the bulbs on, print -1.

Example

input

3

9546

0000

3313

output

4
-1
6

Note

In the first example, all the colors are different, so you can just turn all the bulbs on in 44 operations.

In the second example, it is impossible to turn all the bulbs on, because after you switch one light bulb, it is impossible to turn the others on.

In the third example, you can proceed as follows: turn the first light bulb on, turn the third light bulb on, turn the fourth light bulb on, turn the third light bulb off, turn the second light bulb on, turn the third light bulb on.

题面翻译

给你四个关闭的灯泡,每次打开或关闭一个,不能连续两次操作相同颜色的灯泡(数字相同为同色),问全部打开需要的最少次数

思路:

找规律,全部相同时,不能全部打开;三个相同时,操作6次;其他情况操作4次

代码

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cin>>n;
    while(n--){
        string s;
        cin>>s;
        int t[10];
        for(int i=0;i<4;i++){
            t[i]=s[i]-'0';
        }
        sort(t,t+4);

        if(t[0]==t[3]){
            cout<<-1<<endl;
            continue;
        }

        if(t[0]==t[2]||t[1]==t[3]){
            cout<<6<<endl;
            continue;
        }

        cout<<4<<endl;
    }
    return 0;
}

B. Points on Plane(数学)

You are given a two-dimensional plane, and you need to place n chips on it.

You can place a chip only at a point with integer coordinates. The cost of placing a chip at the point (x,y) is equal to |x|+|y|| (where |a|s the absolute value of a).

The cost of placing n chips is equal to the maximum among the costs of each chip.

You need to place n chips on the plane in such a way that the Euclidean distance between each pair of chips is strictly greater than 1, and the cost is the minimum possible.

Input

The first line contains one integer t (1≤t≤104) — the number of test cases. Next t cases follow.

The first and only line of each test case contains one integer n (1≤n≤1018) — the number of chips you need to place.

Output

For each test case, print a single integer — the minimum cost to place n chips if the distance between each pair of chips must be strictly greater than 1.

Example

input

4

1

3

5

975461057789971042

output

0
1
2
987654321

Note

In the first test case, you can place the only chip at point (0,0) with total cost equal to 0+0=0.

In the second test case, you can, for example, place chips at points (−1,0),(0,1) and (1,0) with costs |−1|+|0|=1, |0|+|1|=1 and |0|+|1|=1. Distance between each pair of chips is greater than 11 (for example, distance between (−1,0)(−1,0) and (0,1)(0,1) is equal to 2–√2). The total cost is equal to max(1,1,1)=1max(1,1,1)=1.

In the third test case, you can, for example, place chips at points (−1,−1)(−1,1), (1,1)(1,1), (0,0)(0,0) and (0,2)(0,2). The total cost is equal to max(2,2,2,0,2)=2.

题面翻译

在平面上放置n个点,使任意两点间的曼哈顿距离大于1,每个点消费为横纵坐标绝对值的和
求消费最大的点的最小消费

思路:

注意到实质为以(0,0)为圆心画正方形,顶点为(k,0),边长为 (k+1)*根号2 ,可以包含(k+1)^2个点
只要把给定的n开方后向上取整,然后-1即可

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll Ce(ll n){    //向上取整
    if(n!=(ll)n)return (ll)n+1;
    return n;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        ll n;
        cin>>n;
        if(n==1){
            cout<<0<<endl;
            continue;
        }
        if(n<=4){
            cout<<1<<endl;
            continue;
        }

        ll ans=Ce((ll)sqrt(n))-2;
        while(ans*ans<n)ans++;      //处理ll直接开方的精度丢失问题
        cout<<ans-1<<endl;
    }
    return 0;
}

C. Sum on Subarray(构造)

For an array a=[a1,a2,…,an] let's denote its subarray a[l,r]as the array [al,al+1,…,ar]

For example, the array a=[1,−3,1] has 66 non-empty subarrays:

  • a[1,1]=[1
  • a[1,2]=[1,−3]
  • a[1,3]=[1,−3,1]
  • a[2,2]=[−3]
  • a[2,3]=[−3,1]
  • a[3,3]=[1]

You are given two integers n and k Construct an array a consisting of n integers such that:

  • all elements of a are from −1000 to 1000;
  • a has exactly ksubarrays with positive sums;
  • the rest (n+1)⋅n2−k subarrays of a have negative sums.

Input

The first line contains one integer t (1≤t≤5000) — the number of test cases.

Each test case consists of one line containing two integers n and k (2≤n≤30; 0≤k≤(n+1)⋅n2).

Output

For each test case, print n integers — the elements of the array meeting the constraints. It can be shown that the answer always exists. If there are multiple answers, print any of them.

Example

input

4

3 2

2 0

2 2

4 6

output

1 -3 1
-13 -42
-13 42
-3 -4 10 -2

题面翻译:

构造一个长为n的序列,他的k个连续子序列和为正数,其他连续子序列和为负数

思路:

贪心构造

如果k小于n,有一个大正数和k-1个小负数,剩下都是负无穷大

否则先把所有都赋值为-2,从前往后第i个数可以构成n-i+1个子序列,如果这些子序列能全为正数则赋为正无穷大,否则赋为1+2*(k-1),k为剩下的正数个数

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100];
int main(){
    int t;
    cin>>t;
    while(t--){
        int n,k;
        cin>>n>>k;
        
        if(k<=n){       //正数个数小于n
            a[1]=100;
            for(int i=1;i<=k-1;i++){
                a[1+i]=-1;
            }
            for(int i=k+1;i<=n;i++){    //剩下全为负无穷
                a[i]=-999;
            }
            for(int i=1;i<=n;i++){
                cout<<a[i]<<' ';
            }
            cout<<endl;
            continue;
        }
        
        int t=n,cnt=1;      //正数个数大于n
        while(k>=t){    //贪心赋值,能把首数赋为正无穷则赋值
            a[cnt++]=100;
            k-=t;
            t-=1;
            if(k==0)break;
        }
        
        for(int i=cnt;i<=n;i++){    //其他都是-2,-1不便于接下来的构造
            a[i]=-2;
        }
        
        a[cnt]=1+2*(k-1);       //接下来这位补齐剩下的k个正数序列
        
        for(int i=1;i<=n;i++){
            cout<<a[i]<<' ';
        }
        cout<<endl;
    }
    return 0;
}

D. Binary String Sorting

You are given a binary string s consisting of only characters 0 and/or 1.

You can perform several operations on this string (possibly zero). There are two types of operations:

  • choose two consecutive elements and swap them. In order to perform this operation, you pay 10^12 coins;
  • choose any element from the string and remove it. In order to perform this operation, you pay 10^12+1 coins.

Your task is to calculate the minimum number of coins required to sort the string s in non-decreasing order (i. e. transform s so that s1≤s2≤⋯≤sm, where m is the length of the string after applying all operations). An empty string is also considered sorted in non-decreasing order.

Input

The first line contains a single integer t (1≤t≤104) — the number of test cases.

The only line of each test case contains the string s (1≤|s|≤3⋅105), consisting of only characters 0 and/or 1.

The sum of lengths of all given strings doesn't exceed 3⋅105

Output

For each test case, print a single integer — the minimum number of coins required to sort the string s in non-decreasing order.

Example

input

6

100

0

0101

00101101

1001101

11111

output

1000000000001
0
1000000000000
2000000000001
2000000000002
0

Note

In the first example, you have to remove the 11-st element, so the string becomes equal to 00.

In the second example, the string is already sorted.

In the third example, you have to swap the 22-nd and the 33-rd elements, so the string becomes equal to 0011.

In the fourth example, you have to swap the 33-rd and the 44-th elements, so the string becomes equal to 00011101, and then remove the 77-th element, so the string becomes equal to 0001111.

In the fifth example, you have to remove the 11-st element, so the string becomes equal to 001101, and then remove the 55-th element, so the string becomes equal to 00111.

In the sixth example, the string is already sorted.

题面翻译

给定一个01串,进行交换01操作或删除操作,使串变为不存在递减的串
交换花费10^12,删除花费10^12+1,求最小花费

思路:

动态规划,一位一位扫过去,转移状态即可

三种状态分别为 0结尾,一个1结尾,多个1结尾,状态转移方程如下

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    int t;
    cin>>t;
    ll c1=1000000000000,c2=1000000000001;
    while(t--){
        string s;
        cin>>s;
        int n=s.length();
        s=" "+s;
        
        //dp[i][j]    //j=0表示末尾为..00     1表示..01    2表示..1..1
        vector<array<ll,3> >dp(n+1,{(ll)1e18,(ll)1e18,(ll)1e18});   //array为静态数组,初始化要加大括号
                //开动态数组初始化为正无穷,静态数组memset亲测TLE
        dp[0][0]=0;
        
        for(int i=1;i<=n;i++){
                
            if(s[i]=='0'){
                dp[i][0]=min(dp[i-1][0],dp[i-1][1]+c2);     //直接填或删1
                dp[i][1]=dp[i-1][1]+c1;     //最后两位交换
                dp[i][2]=dp[i-1][2]+c2;     //删0
            }
            
            if(s[i]=='1'){
                dp[i][0]=dp[i-1][0]+c2;     //把最后的1删去
                dp[i][1]=min(dp[i-1][0],dp[i-1][1]+c2);     //直接填或删1
                dp[i][2]=min(dp[i-1][1],dp[i-1][2]);        //直接填
            }
        }
        
        ll ans=LLONG_MAX;
        for(int i=0;i<3;i++){
            ans=min(ans,dp[n][i]);      //输出最小
        }
        cout<<ans<<endl;
    }
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Auroraaaaaaaaaaaaa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值