目录
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,求最小花费
思路:
动态规划,一位一位扫过去,转移状态即可文章来源:https://www.toymoban.com/news/detail-406018.html
三种状态分别为 0结尾,一个1结尾,多个1结尾,状态转移方程如下文章来源地址https://www.toymoban.com/news/detail-406018.html
代码
#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;
}
到了这里,关于Educational Codeforces Round 145 Div. 2 题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!