Codeforces Round #640 (Div. 4)---题目+详解+代码(全题目)

A. Sum of Round Numbers

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
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 1 to 9 (inclusive) are round.

For example, the following numbers are round: 4000, 1, 9, 800, 90. The following numbers are not round: 110, 707, 222, 1001.

You are given a positive integer n (1≤n≤104). Represent the number n as a sum of round numbers using the minimum number of summands (addends). In other words, you need to represent the given number n as a sum of the least number of terms, each of which is a round number.

Input
The first line contains an integer t (1≤t≤104) — the number of test cases in the input. Then t test cases follow.

Each test case is a line containing an integer n (1≤n≤104).

Output
Print t answers to the test cases. Each answer must begin with an integer k — the minimum number of summands. Next, k terms must follow, each of which is a round number, and their sum is n. The terms can be printed in any order. If there are several answers, print any of them.

Example
inputCopy
5
5009
7
9876
10000
10
outputCopy
2
5000 9
1
7
4
800 70 6 9000
1
10000
1
10

题意:
题意就是按权分解,给你一个数,需要你把这个数各个位上的数按权拿出来,比如1234 分解出1000+200+30+4。

思路:
将上述9876各个位置的数取出,6,7,8,9,同时别忘了,还要还原出具体位置,6(6),7(70),8(800),9(9000).
题目比较简单,就不多说了,直接贴代码啦

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
	int n, m, i, j[10], k, t, l, o;
	scanf("%d", &n);
	while (n--)
	{
		scanf("%d", &m);
		for (i = 0, t = 0, l = 1; m>0; i++)
		{
			j[i] = (m % 10)*l;
			if (j[i])
			{
				t++;
			}
			l *= 10;
			m = m / 10;
		}
		o = i;
		printf("%d\n", t);
		for (i = 0; i < o; i++)
		{
			if (j[i])
			{
				printf("%d ", j[i]);
			}
		}
		printf("\n");
	}
	return 0;
}

B. Same Parity Summands

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given two positive integers n (1≤n≤109) and k (1≤k≤100). Represent the number n as the sum of k positive integers of the same parity (have the same remainder when divided by 2).

In other words, find a1,a2,…,ak such that all ai>0, n=a1+a2+…+ak and either all ai are even or all ai are odd at the same time.

If such a representation does not exist, then report it.

Input
The first line contains an integer t (1≤t≤1000) — the number of test cases in the input. Next, t test cases are given, one per line.

Each test case is two positive integers n (1≤n≤109) and k (1≤k≤100).

Output
For each test case print:

YES and the required values ai, if the answer exists (if there are several answers, print any of them);
NO if the answer does not exist.
The letters in the words YES and NO can be printed in any case.

Example
input
8
10 3
100 4
8 7
97 2
8 8
3 10
5 3
1000000000 9
output
YES
4 2 4
YES
55 5 5 35
NO
NO
YES
1 1 1 1 1 1 1 1
NO
YES
3 1 1
YES
111111110 111111110 111111110 111111110 111111110 111111110 111111110 111111110 111111120

题意:
问一个数n能否分成k个大于0的奇数或k个大于0的偶数

思路:
如果能分成k个大于0的奇数的话,一定能够分出(k-1)个1并且剩下的数一定大于0且是奇数。

代码

#include <iostream>
using namespace std;
int main() {
	int t;
	cin >> t;
	while (t--) {
		int n, k;
		cin >> n >> k;
		int n1 = n - (k - 1);
		//把k-1个1去掉看是不是奇数 
		if (n1 > 0 && n1 % 2 == 1) {
			cout << "YES" << endl;
			for (int i = 0; i < k - 1; i ++ ) cout << "1 ";
			cout << n1 << endl;
			continue;
		}
		int n2 = n - 2 * (k - 1);
		//把k-1个2去掉看是不是偶数 
		if (n2 > 0 && n2 % 2 == 0) {
			cout << "YES" << endl;
			for (int i = 0; i < k - 1; i ++ ) cout << "2 ";
			cout << n2 << endl;
			continue;
		}
		//上述情况都不是则无解 
		cout << "NO" << endl;
	}
}

C. K-th Not Divisible by n

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given two positive integers n and k. Print the k-th positive integer that is not divisible by n.

For example, if n=3, and k=7, then all numbers that are not divisible by 3 are: 1,2,4,5,7,8,10,11,13…. The 7-th number among them is 10.

Input
The first line contains an integer t (1≤t≤1000) — the number of test cases in the input. Next, t test cases are given, one per line.

Each test case is two positive integers n (2≤n≤109) and k (1≤k≤109).

Output
For each test case print the k-th positive integer that is not divisible by n.

Example
inputCopy
6
3 7
4 12
2 1000000000
7 97
1000000000 1000000000
2 1
outputCopy
10
15
1999999999
113
1000000001
1

题意:
给定两个数n、k,求第k个不能被n整除的数是多少。

思路:
如果把数轴分为长度为n的一段一段,那么每一段里面肯定有n-1个数字不能整除n,我们只要查一下第k个数字在那一段即可。

代码:

#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
const int maxn=1e9+7;
int main(){
    int T;
    cin >> T;
    while(T--){
        int n,k;
        cin >> n >> k;
        int t=k/(n-1);
        int res=k-t*(n-1);
        if(k==t*(n-1))res--;
        res+=t*n;
        cout << res << "\n";
    }
}

D. Alice, Bob and Candies

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
There are n candies in a row, they are numbered from left to right from 1 to n. The size of the i-th candy is ai.

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).

Alice makes the first move. During the first move, she will eat 1 candy (its size is a1). Then, each successive move the players alternate — that is, Bob makes the second move, then Alice, then again Bob and so on.

On each move, a player counts the total size of candies eaten during the current move. Once this number becomes strictly greater than the total size of candies eaten by the other player on their previous move, the current player stops eating and the move ends. In other words, on a move, a player eats the smallest possible number of candies such that the sum of the sizes of candies eaten on this move is strictly greater than the sum of the sizes of candies that the other player ate on the previous move. If there are not enough candies to make a move this way, then the player eats up all the remaining candies and the game ends.

For example, if n=11 and a=[3,1,4,1,5,9,2,6,5,3,5], then:

move 1: Alice eats one candy of size 3 and the sequence of candies becomes [1,4,1,5,9,2,6,5,3,5].
move 2: Alice ate 3 on the previous move, which means Bob must eat 4 or more. Bob eats one candy of size 5 and the sequence of candies becomes [1,4,1,5,9,2,6,5,3].
move 3: Bob ate 5 on the previous move, which means Alice must eat 6 or more. Alice eats three candies with the total size of 1+4+1=6 and the sequence of candies becomes [5,9,2,6,5,3].
move 4: Alice ate 6 on the previous move, which means Bob must eat 7 or more. Bob eats two candies with the total size of 3+5=8 and the sequence of candies becomes [5,9,2,6].
move 5: Bob ate 8 on the previous move, which means Alice must eat 9 or more. Alice eats two candies with the total size of 5+9=14 and the sequence of candies becomes [2,6].
move 6 (the last): Alice ate 14 on the previous move, which means Bob must eat 15 or more. It is impossible, so Bob eats the two remaining candies and the game ends.
Print the number of moves in the game and two numbers:

a — the total size of all sweets eaten by Alice during the game;
b — the total size of all sweets eaten by Bob during the game.
Input
The first line contains an integer t (1≤t≤5000) — the number of test cases in the input. The following are descriptions of the t test cases.

Each test case consists of two lines. The first line contains an integer n (1≤n≤1000) — the number of candies. The second line contains a sequence of integers a1,a2,…,an (1≤ai≤1000) — the sizes of candies in the order they are arranged from left to right.

It is guaranteed that the sum of the values of n for all sets of input data in a test does not exceed 2⋅105.

Output
For each set of input data print three integers — the number of moves in the game and the required values a and b.

Example
inputCopy
7
11
3 1 4 1 5 9 2 6 5 3 5
1
1000
3
1 1 1
13
1 2 3 4 5 6 7 8 9 10 11 12 13
2
2 1
6
1 1 1 1 1 1
7
1 1 1 1 1 1 1
outputCopy
6 23 21
1 1000 0
2 1 2
6 45 46
2 2 1
3 4 2
4 4 3

题意:
一共有n堆糖,Alice是从左边开始吃,而Bob从右边开始吃,两个人轮流吃,Alice先开始,下一次吃的人要比上一次吃的人多,最后求出两个人每个人吃了多少颗糖果,以及轮流了多少次。

思路:
模拟过程即可

#include<bits/stdc++.h>
using namespace std;

int c[1010];
int main()
{
    int t;cin>>t;
    while(t--){
        int n ;cin>>n;
        for(int i=1;i<=n;i++)
            cin>>c[i];
        int l = 1,r = n;
        int count1=0;
        int flag = 0,x=0;
        int a=0,b=0,now;
        while(l<=r){
            if(flag==0){
                now = 0;
                while(x>=now&&l<=r){
                    now = now+c[l++];
                }
                a = a+now;
                flag = 1;count1++;
            }
            else{
                now = 0;
                while(x>=now&&l<=r){
                    now = now+c[r--];
                }
                b = b+now;
                //cout<<"b"<<" "<<b;
                flag = 0; count1++;
            }
            x = now;
        }
        cout<<count1<<" "<<a<<" "<<b<<endl;
    }
    return 0;
}

E. Special Elements

time limit per test1 second
memory limit per test64 megabytes
inputstandard input
outputstandard output
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.

The array a=[a1,a2,…,an] (1≤ai≤n) is given. Its element ai is called special if there exists a pair of indices l and r (1≤l<r≤n) such that ai=al+al+1+…+ar. In other words, an element is called special if it can be represented as the sum of two or more consecutive elements of an array (no matter if they are special or not).

Print the number of special elements of the given array a.

For example, if n=9 and a=[3,1,4,1,5,9,2,6,5], then the answer is 5:

a3=4 is a special element, since a3=4=a1+a2=3+1;
a5=5 is a special element, since a5=5=a2+a3=1+4;
a6=9 is a special element, since a6=9=a1+a2+a3+a4=3+1+4+1;
a8=6 is a special element, since a8=6=a2+a3+a4=1+4+1;
a9=5 is a special element, since a9=5=a2+a3=1+4.
Please note that some of the elements of the array a may be equal — if several elements are equal and special, then all of them should be counted in the answer.

Input
The first line contains an integer t (1≤t≤1000) — the number of test cases in the input. Then t test cases follow.

Each test case is given in two lines. The first line contains an integer n (1≤n≤8000) — the length of the array a. The second line contains integers a1,a2,…,an (1≤ai≤n).

It is guaranteed that the sum of the values of n for all test cases in the input does not exceed 8000.

Output
Print t numbers — the number of special elements for each of the given arrays.

Example
inputCopy
5
9
3 1 4 1 5 9 2 6 5
3
1 1 2
5
1 1 1 1 1
8
8 7 6 5 4 3 2 1
1
1
outputCopy
5
1
0
4
0
题意:
给定n个数,如果a[i]=sum(a[l-r])(1<=l<r<=n),那么称a[i]为一个特殊数,求这n个数中特殊数的个数。
思路:
可用前缀和,计算出任意一段连续数组元素的和,看看是否与某个数组元素相同,若相同,该数组元素即为特殊的。注意,此时,该数组元素参与计数,并打上访问过的标记,该数组元素不参与之后的相等判定了。

AC时间到

#include <stdio.h>
#define maxn 8010
int a[maxn],cnt[maxn],sum[maxn],vis[maxn];//cnt[]运用了桶排序的思想。
int main(){
	int t,n,i,j,b,tot;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		for(i=1;i<=n;i++)cnt[i]=0,vis[i]=0;//vis[i]给访问过的Special Element打上标记,避免重复计算。
		for(i=1;i<=n;i++)scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i],cnt[a[i]]++;//前缀和,桶排序
		tot=0;
		for(i=1;i<=n;i++)
			for(j=i+1;j<=n;j++){//注意j=i+1,因为two or more consecutive elements
				b=sum[j]-sum[i-1];//b表示数组脚标区间[i,j]之间的数组元素连续和。
				if(b<=n&&cnt[b]&&vis[b]==0)tot+=cnt[b],vis[b]=1;//关键点b<=n,这样cnt[b],vis[b]两个数组脚标就不会越界。
			}
		printf("%d\n",tot);
	}
	return 0;
}

F. Binary String Reconstruction

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
For some binary string s (i.e. each character si is either ‘0’ or ‘1’), all pairs of consecutive (adjacent) characters were written. In other words, all substrings of length 2 were written. For each pair (substring of length 2), the number of ‘1’ (ones) in it was calculated.

You are given three numbers:

n0 — the number of such pairs of consecutive characters (substrings) where the number of ones equals 0;
n1 — the number of such pairs of consecutive characters (substrings) where the number of ones equals 1;
n2 — the number of such pairs of consecutive characters (substrings) where the number of ones equals 2.
For example, for the string s=“1110011110”, the following substrings would be written: “11”, “11”, “10”, “00”, “01”, “11”, “11”, “11”, “10”. Thus, n0=1, n1=3, n2=5.

Your task is to restore any suitable binary string s from the given values n0,n1,n2. It is guaranteed that at least one of the numbers n0,n1,n2 is greater than 0. Also, it is guaranteed that a solution exists.

Input
The first line contains an integer t (1≤t≤1000) — the number of test cases in the input. Then test cases follow.

Each test case consists of one line which contains three integers n0,n1,n2 (0≤n0,n1,n2≤100; n0+n1+n2>0). It is guaranteed that the answer for given n0,n1,n2 exists.

Output
Print t lines. Each of the lines should contain a binary string corresponding to a test case. If there are several possible solutions, print any of them.

Example
inputCopy
7
1 3 5
1 1 1
3 9 3
0 1 0
3 1 2
0 0 3
2 0 0
outputCopy
1110011110
0011
0110001100101011
10
0000111
1111

题意:
要你构造出一个01字串满足每相邻的一对元素中,0,1,2个‘1’中的个数。

思路:
如果n1=0,那么n0和n2必有一个为0,只需要输出不为0的那种,如果n1不为0,我们先输出n0的,然后接上n2的,注意此时交界处有一个01,所以对n1–,最后补上n1就行。

代码

#include <stdio.h>
#include <string.h>
char s[400];
int main(){
	int t,a,b,c,i,len;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d%d",&a,&b,&c);
		len=0;
		if(a>0){//先处理a对00
			for(i=0;i<=a;i++)s[i]='0';
			len=a+1;
		}
		if(c>0){//再处理c对11
			if(len>0)b--;//要判定开始11类型时,之前的字母是否是0.len>0,之前字母是0
			for(i=len;i<=len+c;i++)s[i]='1';
			len=len+c+1;
		}
		if(b>0){//最后处理b对(01或10)
			if(len==0){//当前字串长度是0.1对(01或10)形态:01;  2对 010;  3对 0101;  4对 01010
				s[0]='0';
				for(i=1;i<=b;i++)
					if(i%2)s[i]='1';
					else s[i]='0';
				len=b+1;
			}
			else if(s[len-1]=='1'){//前面是1.1对(01或10)形态:0;  2对:01;  3对:010;  4对:0101
				for(i=len;i<len+b;i++)
					if((i-len)%2==0)s[i]='0';
					else s[i]='1';
				len=len+b;
			}else if(s[len-1]=='0'){//前面是0.1对(01或10)形态:1;  2对:10;  3对:101
				for(i=len;i<len+b;i++)
					if((i-len)%2==0)s[i]='1';
					else s[i]='0';
				len=len+b;
			}
		}
		s[len]='\0';
		printf("%s\n",s);
	}
	return 0;
}

G. Special Permutation

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
A permutation of length n is an array p=[p1,p2,…,pn], which contains every integer from 1 to n (inclusive) and, moreover, each number appears exactly once. For example, p=[3,1,4,2,5] is a permutation of length 5.

For a given number n (n≥2), find a permutation p in which absolute difference (that is, the absolute value of difference) of any two neighboring (adjacent) elements is between 2 and 4, inclusive. Formally, find such permutation p that 2≤|pi−pi+1|≤4 for each i (1≤i<n).

Print any such permutation for the given integer n or determine that it does not exist.

Input
The first line contains an integer t (1≤t≤100) — the number of test cases in the input. Then t test cases follow.

Each test case is described by a single line containing an integer n (2≤n≤1000).

Output
Print t lines. Print a permutation that meets the given requirements. If there are several such permutations, then print any of them. If no such permutation exists, print -1.

Example
inputCopy
6
10
2
4
6
7
13
outputCopy
9 6 10 8 4 7 3 1 5 2
-1
3 1 4 2
5 3 6 2 4 1
5 1 3 6 2 4 7
13 9 7 11 8 4 1 3 5 2 6 10 12

题意:
就是一个n,要你写出一个全排列满足所有相邻元素差值的绝对值大于等于2小于等于4.
思路:
找规律,四个一循环,可以一直循环,然后最后一组四个和最后剩下的特判输出就可以。

代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        if(n<=3)
        {
            cout<<-1<<endl;
            continue;
        }
        int mm=n%4;
        int tt=n/4;
        for(int i=1;i<=tt-1;i++)
        {
            int t=(i-1)*4;
            cout<<t+2<<' '<<t+4<<' '<<t+1<<' '<<t+3<<' ';
        }
        if(mm==0)
            cout<<(tt-1)*4+3<<' '<<(tt-1)*4+1<<' '<<(tt-1)*4+4<<' '<<(tt-1)*4+2<<endl;
        if(mm==1)
            cout<<(tt-1)*4+1<<' '<<(tt-1)*4+4<<' '<<(tt-1)*4+2<<' '<<(tt-1)*4+5<<' '<<(tt-1)*4+3<<endl;
        if(mm==2)
            cout<<(tt-1)*4+1<<' '<<(tt-1)*4+4<<' '<<(tt-1)*4+2<<' '<<(tt-1)*4+5<<' '<<(tt-1)*4+3<<' '<<(tt-1)*4+6<<endl;
        if(mm==3)
            cout<<(tt-1)*4+1<<' '<<(tt-1)*4+4<<' '<<(tt-1)*4+2<<' '<<(tt-1)*4+6<<' '<<(tt-1)*4+3<<' '<<(tt-1)*4+5<<' '<<(tt-1)*4+7<<endl;

    }
return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值