Codeforces Round #696 Div.2
A.Puzzle From the Future
题目描述
In the 2022 year, Mike found two binary integers a and b of length n (both of them are written only by digits 0 and 1) that can have leading zeroes. In order not to forget them, he wanted to construct integer d in the following way:
· he creates an integer c as a result of bitwise summing of a and b without transferring carry, so c may have one or more 2-s. For example, the result of bitwise summing of 0110 and 1101 is 1211 or the sum of 011000 and 011000 is 022000;
· after that Mike replaces equal consecutive digits in c by one digit, thus getting d. In the cases above after this operation, 1211 becomes 121 and 022000 becomes 020 (so, d won’t have equal consecutive digits)
Unfortunately, Mike lost integer a before he could calculate d himself. Now, to cheer him up, you want to find any binary integer a of length n such that d will be maximum possible as integer.
Maximum possible as integer means that 102>21, 012<101, 021=21 and so on.
Input
The first line contains a single integer t (1≤t≤1000) — the number of test cases.
The first line of each test case contains the integer n (1≤n≤ 1 0 5 10^5 105) — the length of a and b.
The second line of each test case contains binary integer b of length n. The integer b consists only of digits 0 and 1.
It is guaranteed that the total sum of n over all t test cases doesn’t exceed 1 0 5 10^5 105.
Output
For each test case output one binary integer a of length n. Note, that a or b may have leading zeroes but must have the same length n.
Example
Input
5
1
0
3
011
3
110
6
111000
6
001011
Output
1
110
100
101101
101110
解题思路
对于给出的字长为n的二进制串a,要求给出字长为n的二进制串b,满足串d=a+b的值最大,例如a=1110,b=1001,那么d=2111,注意串d中连续的数字将被压缩为一个,例如022000压缩为020。
那么设置一个flag表示从高位开始,前一个位相加的结果,初始状态设为0,如果相加为2则flag置为2,相加为1置为1,相加为0置为0;可以从最高位开始,尽可能的取最大值。
这题一遍A的,没有遇到什么小坑
Code
#include<bits/stdc++.h>
using namespace std;
int main(){
int Case;
cin>>Case;
while(Case--){
string str,ans;
int n;
cin>>n;
cin>>str;
ans="";
int flag=0;
for(int i=0;i<n;i++){
if(str[i]=='1'){
if(flag!=2){
ans+='1';
flag=2;
}
else{
ans+='0';
flag=1;
}
}
else{
if(flag!=1){
ans+='1';
flag=1;
}
else{
ans+='0';
flag=0;
}
}
}
cout<<ans<<endl;
}
return 0;
}
B.Different Divisors
题目描述
Positive integer x is called divisor of positive integer y, if y is divisible by x without remainder. For example, 1 is a divisor of 7 and 3 is not divisor of 8.
We gave you an integer d and asked you to find the smallest positive integer a, such that
· a has at least 4 divisors;
· difference between any two divisors of a is at least d.
Input
The first line contains a single integer t ( 1 ≤ t ≤ 3000 ) t (1≤t≤3000) t(1≤t≤3000) — the number of test cases.
The first line of each test case contains a single integer d ( 1 ≤ d ≤ 10000 ) d (1≤d≤10000) d(1≤d≤10000).
Output
For each test case print one integer a — the answer for this test case.
Example
Input
2
1
2
Output
6
15
Note
In the first test case, integer 6 have following divisors:
[
1
,
2
,
3
,
6
]
[1,2,3,6]
[1,2,3,6]. There are 4 of them and the difference between any two of them is at least 1. There is no smaller integer with at least 4 divisors.
In the second test case, integer 15 have following divisors: [ 1 , 3 , 5 , 15 ] [1,3,5,15] [1,3,5,15]. There are 4 of them and the difference between any two of them is at least 2.
The answer 12 is INVALID because divisors are [ 1 , 2 , 3 , 4 , 6 , 12 ] [1,2,3,4,6,12] [1,2,3,4,6,12]. And the difference between, for example, divisors 2 and 3 is less than d=2.
解题思路
[题意解读] 给出d,要求得出最小一个数满足:①至少有四个除数②这些除数因子之间至少相差d。
[思路分析]
首先,有四个除数,有两个一定是1和自己本身,那么再找两个除数就可以。
在看到这道题的时候第一个想法是
(
1
+
d
)
(
1
+
2
d
)
(1+d)(1+2d)
(1+d)(1+2d),然后发现这样得出的数还可能有其他的除数,它们可能不满足相差为
d
d
d的条件。
因此这两个除数应该为素数。由于
1
≤
d
≤
10000
1≤d≤10000
1≤d≤10000,那么暴力找应该就能过。因此第一个除数
x
x
x从
(
1
+
d
)
(1+d)
(1+d)开始往上查找,如果为素数则退出,第二个除数从
(
x
+
d
)
(x+d)
(x+d)开始往上查找,同样为素数则退出。结果很明显就是
x
y
xy
xy,接下来就是code了
这题思路清晰就没有什么其他太大的问题了。冲冲冲
Code
#include<bits/stdc++.h>
using namespace std;
bool isPrime(int x){
if(x==2) return true;
int sq=sqrt(x);
for(int i=2;i<=sq;i++){
if(x%i==0) return false;
}
return true;
}
int main(){
int Case;
cin>>Case;
while(Case--){
int d;
cin>>d;
int x,y;
for(int i=1+d;i;i++){
if(isPrime(i)){
x=i;
break;
}
}
for(int i=x+d;i;i++){
if(isPrime(i)){
y=i;
break;
}
}
cout<<x*y<<endl;
}
return 0;
}
C. Array Destruction
题目描述
You found a useless array a of 2n positive integers. You have realized that you actually don’t need this array, so you decided to throw out all elements of a.
It could have been an easy task, but it turned out that you should follow some rules:
- In the beginning, you select any positive integer x.
- Then you do the following operation n times:
· select two elements of array with sum equals x;
· remove them from a and replace x with maximum of that two numbers.
For example, if initially a=[3,5,1,2], you can select x=6. Then you can select the second and the third elements of a with sum 5+1=6 and throw them out. After this operation, x equals 5 and there are two elements in array: 3 and 2. You can throw them out on the next operation.
Note, that you choose x before the start and can’t change it as you want between the operations.
Determine how should you behave to throw out all elements of a.
Input
he first line contains a single integer t ( 1 ≤ t ≤ 1000 ) t (1≤t≤1000) t(1≤t≤1000) — the number of test cases.
The first line of each test case contains the single integer n ( 1 ≤ n ≤ 1000 ) n (1≤n≤1000) n(1≤n≤1000).
The second line of each test case contains 2n integers a 1 , a 2 , … , a 2 n a1,a2,…,a2n a1,a2,…,a2n ( 1 ≤ a i ≤ 1 0 6 ) (1≤ai≤10^6) (1≤ai≤106) — the initial array a a a.
It is guaranteed that the total sum of n n n over all test cases doesn’t exceed 1000.
Output
For each test case in the first line print YES if it is possible to throw out all elements of the array and NO otherwise.
If it is possible to throw out all elements, print the initial value of x x x you’ve chosen. Print description of n n n operations next. For each operation, print the pair of integers you remove.
Example
Input
4
2
3 5 1 2
3
1 1 8 8 64 64
2
1 1 2 4
5
1 2 3 4 5 6 7 14 3 11
Output
YES
6
1 5
2 3
NO
NO
YES
21
14 7
3 11
5 6
2 4
3 1
Note
The first test case was described in the statement.
In the second and third test cases, we can show that it is impossible to throw out all elements of array a a a.
解题思路
[题目解读]
对于给出的2*n个数字,经过n次操作,全部删除。操作如下:
①首先选定一个x
②在这个数组中找到两个和为x的值,删去,同时x被替换为这两个数中更大的那个值
[思路分析]
由于
1
≤
n
≤
1000
1≤n≤1000
1≤n≤1000,因此暴力是能过的。
我们应该很容易知道,在第一操作中,应选择最大的数和另外一个数。接下来的操作中,每次都依次选择剩下来的最大的数 a [ i ] a[i] a[i],而与之匹配的数应该是x-a[i],在剩下的数中查找是否有该数存在。
因此可以选用一个便于删除的容器,最好还是有序的,这里用了vector<pair< int >>ans 来存储最终结果,map<int,int>vis 这个用来存储 a [ i ] a[i] a[i]的出现次数。删除后,vis[a[i]]–。
这题在刚开始写的时候我直接遍历查找每对,没有找到可以先排序然后查找的方法,所以一直TLE。在写的时候还要注意清空vis和ans。
Code
#include<bits/stdc++.h>
using namespace std;
const int maxn=2005;
int a[maxn];
int main(){
int Case;
cin>>Case;
while(Case--){
int n;
cin>>n;
for(int i=1;i<=2*n;i++){
cin>>a[i];
}
sort(a+1,a+2*n+1);
int tmp;
map<int,int>vis;
vector<pair<int,int> >ans;
for(int i=1;i<2*n;i++){
vis.clear();
ans.clear();
for(int j=1;j<=2*n;j++){vis[a[j]]++;}
int x=a[2*n]+a[i];
for(int j=2*n;j>0;j--){
if(!vis[a[j]]) continue;
int need=1;
if(x-a[j]==a[j]) need=2;
if(vis[x-a[j]]>=need){
ans.push_back(make_pair(a[j],x-a[j]));
vis[a[j]]--;
vis[x-a[j]]--;
x=a[j];
}
else break;
}
if(ans.size()==n){
tmp=a[i]+a[2*n];
break;
}
}
if(ans.size()==n){
cout<<"YES"<<endl;
cout<<tmp<<endl;
for(int i=0;i<n;i++){
cout<<ans[i].first<<" "<<ans[i].second<<endl;
}
}
else{
cout<<"NO"<<endl;
}
}
return 0;
}