Codeforces Round #640 (Div. 4)
文章目录
A. Sum of Round Numbers
A positive (strictly greater than zero) integer is called round if it is of the form d00…0. In other words, a positive integer is round if all its digits except the leftmost (most significant) are equal to zero. In particular, all numbers from 11 to 99 (inclusive) are round…
题意:T组数,每组数一个n,输出n各位不为0的总个数,并输出各个的大小。且不要求输出顺序。
如:12304 不为0的位数共4个,分别为个位,百位,千位,万位。故第一行输出 4 ,第二行输出 10000 2000 300 4
直接读入判断各位是否为0,并记录将要输出的每个数大小即可
#include <iostream>
#include <cstring>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
int T, n, res[5], cnt, tmp, i;
int main(){
ios;
cin >> T;
while(T --){
memset(res, 0, sizeof(res));
cnt = 0; i = 0; tmp = 1;
cin >> n;
while (1){
if(n % 10) {
cnt ++;
res[i] = n % 10 * tmp;
i ++;
}
tmp *= 10;
n /= 10;
if (!n)break;
}
cout << cnt << endl;
for (int j = 0; j < i; j ++)
cout << res[j] << ' ';
cout << endl;
}
return 0;
}
B. Same Parity Summands
You are given two positive integers nn (1≤n≤1091≤n≤109) and kk (1≤k≤1001≤k≤100). Represent the number nn as the sum of kk positive integers of the same parity (have the same remainder when divided by 22).
In other words, find a1,a2,…,aka1,a2,…,ak such that all ai>0ai>0, n=a1+a2+…+akn=a1+a2+…+ak and either all aiai are even or all aiai are odd at the same time…
题意:T组数,每组两个数n,k,判断能否由k奇偶性相同的正整数相加得到n。如果能输出YES
并输出所符合的正整数(情况不唯一输出任意一种),如果不能则输出NO
偶 = 奇 + 奇 偶 = 偶 + 偶
奇 = 奇 + 偶数
结合本题要求
- 若n为奇数,则需奇数个奇数相加才为真,故k为奇数。则n 可由k-1个 1 与一个足够大的 奇数 相加得到
- 若n为偶数
- 偶数个奇数相加为偶数,故k为偶数。则n 可由k-1个 1 与一个足够大的 奇数 相加得到
- 任意个偶数偶数相加为偶数。则n 可由k-1个 2与一个足够大的 偶数 相加得到
故先判断n的奇偶,再判断k的奇偶,并根据上述三种情况进行相加判断
代码虽长但均是条件判断
#include <iostream>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
int T, n, k, tmp;
int main(){
ios;
cin >> T;
while (T --){
cin >> n >> k;
if (n < k) cout << "NO" << endl;
else{
tmp = n - (k -1);
if (n % 2)
if (k % 2)
if (tmp % 2){
cout << "YES" << endl;
for (int i = 1; i <= k - 1; i ++) cout << 1 << ' ';
cout << tmp << endl;
}
else cout << "NO" << endl;
else cout << "NO" << endl;
else
if (k % 2 == 0)
if (tmp % 2) {
cout << "YES" << endl;
for (int i = 1; i <= k - 1; i ++) cout << 1 << ' ';
cout << tmp << endl;
}
else cout << "NO" << endl;
else{
tmp = n - 2 * (k - 1);
if (tmp <= 0 || tmp % 2 == 1) cout << "NO" << endl;
else{
cout << "YES" << endl;
for (int i = 1; i <= k - 1; i ++) cout << 2 << ' ';
cout << tmp << endl;
}
}
}
}
return 0;
}
C. K-th Not Divisible by n
You are given two positive integers nn and kk. Print the kk-th positive integer that is not divisible by nn.
For example, if n=3n=3, and k=7k=7, then all numbers that are not divisible by 33 are: 1,2,4,5,7,8,10,11,13…1,2,4,5,7,8,10,11,13…. The 77-th number among them is 10.
题意:T组数据,每组两个数,给定数n和数k,输出第k个不被n整除的数。
题目数据量较大,且是T组,故直接循环输出不可取
简单模拟几个即可发现规律,从1开始每n个数,存在n-1个不可被n整除的数。故不可被整除的数每n-1个数为一组 对应原数为每n个为一组。最总最求为原数,故结果为 组数*n + k % n-1。注意当k刚好为n的倍数时,第k个数所指为最后一组第n -1 个数。
#include <iostream>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
int T, n, k;
int main(){
ios;
cin >> T;
while (T --){
cin >> n >> k;
if (k % (n - 1) == 0)
cout << k / (n - 1) * n - 1 << endl;
else cout << k / (n - 1) * n + k % (n - 1) << endl;
}
return 0;
}
D. Alice, Bob and Candies
There are nn candies in a row, they are numbered from left to right from 11 to nn. The size of the ii-th candy is aiai.
Alice and Bob play an interesting and tasty game: they eat candy. Alice will eat candy from left to right, and Bob — from right to left. The game ends if all the candies are eaten.
The process consists of moves. During a move, the player eats one or more sweets from her/his side (Alice eats from the left, Bob — from the right)…
题意:有n颗糖果,A从左往右吃,B从右往左吃,AB交替进行,由A先开始,且每个人吃的都要比上一个人吃的严格多,最后一次除外,吃完结束。输出总步数和两人各吃糖果数量
题目很长也很简单,简单模拟就可实现,方法较多,这里用双端队列写一下。
#include <iostream>
#include <deque>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
int T, n, x, tmpa, tmpb, resa, resb, cnt, flag;
deque <int> dq;
int main(){
ios;
cin >> T;
while (T --){
resa = 0, resb = 0;
tmpb = 0, cnt = 0, flag = 0;
cin >> n;
while (n --){
cin >> x;
dq.push_back(x);
}
while(!dq.empty()){
tmpa = 0;
while (tmpa <= tmpb){
tmpa += dq.front();
dq.pop_front();
if(dq.empty()){
flag = 1;
break;
}
}
cnt ++;
resa += tmpa;
if(flag)break;
tmpb = 0;
while (tmpb <= tmpa){
tmpb += dq.back();
dq.pop_back();
if(dq.empty()){
flag = 1;
break;
}
}
cnt ++;
resb += tmpb;
if(flag)break;
}
cout << cnt << ' ' << resa << ' ' << resb << endl;
}
return 0;
}
E. Special Elements
Pay attention to the non-standard memory limit in this problem.
In order to cut off efficient solutions from inefficient ones in this problem, the time limit is rather strict. Prefer to use compiled statically typed languages (e.g. C++). If you use Python, then submit solutions on PyPy. Try to write an efficient solution…
题意:给n个数,如果一个数可以表示为某个大于等于2的区间的和,那么他就是特殊元素,问一共有多少个特殊元素.
前缀和转化一下问题.求出前缀和,并在读入将存储n个数转变为存储数x出现的次数(数据量8e3,可开cnt[8e3])。任意大于等于2的区间的和为sum[r]-sum[l],令其为tmp,从计数数组中找出共有多少个特殊元素。虽然是二重循环,但通过break可减少循环次数。并注意防止越界
#include <iostream>
#include <cstring>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
int T, n, x, mx, sum[8005] = {0}, cnt[8005], tmp, res;
int main(){
ios;
cin >> T;
while (T --){
res = 0, mx = 0;
memset(cnt, 0, sizeof(cnt));
cin >> n;
for (int i = 1; i <= n; i ++){
cin >> x;
mx = max(mx, x);
sum[i] = sum[i - 1] + x;
cnt[x] ++;
}
for (int i = 1; i < n; i ++){
for (int j = i + 1; j <=n ; j ++){
tmp = sum[j] - sum[i - 1];
if(tmp > mx) break;
if (tmp < 8005 && cnt[tmp] != 0) {
res += cnt[tmp];
cnt[tmp] = 0;
}
}
}
cout << res << endl;
}
return 0;
}
F. Binary String Reconstruction
For some binary string ss (i.e. each character sisi is either ‘0’ or ‘1’), all pairs of consecutive (adjacent) characters were written. In other words, all substrings of length 22 were written. For each pair (substring of length 22), the number of ‘1’ (ones) in it was calculated.
For example, for the string s=s=“1110011110”, the following substrings would be written: “11”, “11”, “10”, “00”, “01”, “11”, “11”, “11”, “10”. Thus, n0=1n0=1, n1=3n1=3, n2=5n2=5.
题意:给定"11"的个数n2,"10"和"01"的个数n1,“00"的个数n0,输出可能的字符串。(多种结果,符合即可)
题解当三者均不为0时。0在前,1在后则其交界处必存在一个01,x个00需要x+1个0(11同理)而当存在01时,只需输出x个0即可。交界处为01的重复,故交接处可有奇数个01,x个01对可构造2x-1个01对,故若n1为非零偶数时,则再末尾再次输出一个0,构成10对。当只有0或只有1时由于没有01对来进行前补0后补1,故需要再次输出一个0或1
#include <iostream>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
int T, a, b, c, tmp;
int main(){
ios;
cin >> T;
while (T --){
cin >> a >> b >> c;
for (int i = 1; i <= a; i ++) cout << '0';
tmp = (b + 1) / 2;
for (int i = 1; i <= tmp; i ++) cout << "01";
for (int i = 1; i <= c; i ++) cout << '1';
if (b && b % 2 == 0) cout << '0';
if (b == 0 && c == 0) cout << '0';
if (a == 0 && b == 0) cout << '1';
cout << endl;
}
return 0;
}
G. Special Permutation
A permutation of length nn is an array p=[p1,p2,…,pn]p=[p1,p2,…,pn], which contains every integer from 11 to nn (inclusive) and, moreover, each number appears exactly once. For example, p=[3,1,4,2,5]p=[3,1,4,2,5] is a permutation of length 55.
For a given number nn (n≥2n≥2), find a permutation pp in which absolute difference (that is, the absolute value of difference) of any two neighboring (adjacent) elements is between 22 and 44, inclusive. Formally, find such permutation pp that 2≤|pi−pi+1|≤42≤|pi−pi+1|≤4 for each ii (1≤i<n1≤i<n)…
题意:给定数n,输出长度为n,元素为1~n的数组,其中任意两个相邻元素的差值的绝对值在1-4之间(包含)。若有则输出,没有此数组输出-1。
构造一下即可,容易发现n小于4的时候无法构造。
n = 4时: 3 1 4 2符合,且当 n > 4时可以3 1 4 2为基础左右拓展。
如:
-
n = 5: 5 3 1 4 2
-
n = 6:6 3 1 4 2 5
-
n = 7:7 5 3 1 4 2 6
…奇偶分别左右排布即可
#include <iostream>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
int T, n;
int main(){
ios;
cin >> T;
while (T --){
cin >> n;
if (n < 4)cout << -1 << endl;
else{
for (int i = n; i > 4; i -= 2) cout << i << ' ';
cout << "3 1 4 2 ";
for (int i = 5 + n % 2; i < n; i += 2) cout << i << ' ';
cout << endl;
}
}
return 0;
}