题目:(A) Sum of Round Numbers

题目大意:

给出 t 组数据,对于每组数据将给出的 n ,将其分成若干个数,输出数的个数以及情况 (如901 可分解成 900 1 两个数)。

 

解题代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
const long long N = 1e10 + 7;
const int maxn = 1e6 + 5;
const long long INF = 8e18;
typedef long long ll;
#define for0(i,n) for(int i = 0;i < n;i++)
#define for1(i,n) for(int i = 1;i <= n;i++)
using namespace std;
int x[10];
int main(){
    int t;
    cin >> t;
    while(t--){
        int num,temp = 1,sum = 0;
        cin >> num;
        while(num){
            if(num % 10){
               x[sum++] = num%10 * temp;
            }
            temp *= 10;
            num /= 10;
        }
        cout << sum << endl;
        for0(i,sum)  cout << x[i] << " ";
        cout << endl;

    }
    return 0;
}

 

题目:(B) Same Parity Summands

题目大意:

给出 t 组数据,对于每组数据将给出的 n 分成 k 个奇偶性相同数的和,先判断是否可分,若可分这输出任意一个情况。

思路:

可以将 n 试着分解成 (k-1)个 1 与 n-(k-1)  或者分解成 (k-1)个 2 与 n-2*(k-1)  ,若两种情况都不能进行,则不可分。

解题代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
const long long N = 1e10 + 7;
const int maxn = 1e6 + 5;
const long long INF = 8e18;
typedef long long ll;
#define for0(i,n) for(int i = 0;i < n;i++)
#define for1(i,n) for(int i = 1;i <= n;i++)
using namespace std;
 
int main()
{
   int t,n,k;
   cin >> t;
   while(t--){
        cin >> n >> k;
        if( (n - (k-1)) % 2 && n > (k-1)){    //全部分成奇数
            cout << "YES" << endl;
            for0(i,k-1)  cout << 1 << " ";
            cout << n-(k-1) << endl;
        }
        else if( (n - 2*(k-1)) % 2 == 0 && n > 2*(k-1)){ //全部分成偶数
            cout << "YES" << endl;
            for0(i,k-1)  cout << 2 << " ";
            cout << (n - 2*(k-1)) << endl;
        }
        else
            cout << "NO" << endl;
   }
   return 0;
}

题目:(C) K-th Not Divisible

题目大意:

给出 t 组数据,对于每组数据给出 n 和 k ,输出从 1 开始第 k 个不会被 n 整除的数。

思路:

当 n > k 时自然答案便是 k , 当 n  <= k 时,此时的答案肯定大于 k ,而且寻找数据规律易得答案为 k +  (k-1)/(n-1)。

解题代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
const long long N = 1e10 + 7;
const int maxn = 1e6 + 5;
const long long INF = 8e18;
typedef long long ll;
#define for0(i,n) for(int i = 0;i < n;i++)
#define for1(i,n) for(int i = 1;i <= n;i++)
using namespace std;
 
int main()
{
   int t,n,k;
   cin >> t;
   while(t--){
        cin >> n >> k;
        if(n > k)
            cout << k << endl;
        else{
            cout << k + (k-1)/(n-1) << endl;
        }
   }
   return 0;
}

题目:(D) Alice, Bob and Candies

题目大意:

给出 t 组数据,对于每组数据给出 n 个位置的糖果数,Alice从前往后吃,Bob从后往前吃,Alice先手,并且在本轮吃的糖果尽可能少的情况下,每轮吃的糖果数必须要大于前一轮吃的数量,最后一轮若不符合条件那么就吃掉剩下的全部糖果。输出经过多少个回合全部糖果被次完,Alice所吃糖果数,Bob所吃糖果数。

思路:

设置双指针,不断进行更新。

解题代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
const long long N = 1e10 + 7;
const int maxn = 1e6 + 5;
const long long INF = 8e18;
typedef long long ll;
#define for0(i,n) for(int i = 0;i < n;i++)
#define for1(i,n) for(int i = 1;i <= n;i++)
using namespace std;
int x[1010];
int main()
{
   int t,n;
   cin >> t;
   while(t--){
        cin >> n;
        for0(i,n)  cin >> x[i];
        int movenum = 0,sum1 = 0,sum2 = 0,temp1 = 0,temp2 = 0;
        // sum为两人各自吃糖总数,temp为每轮的吃糖标准
        int i = 0,j = n-1;
        while(i <= j){
 
            if(movenum % 2 == 0){   //Alice的回合
                int num = 0;
                while(i <= j && num <= temp2){
                    num += x[i++];
                }
                temp1 = num;   //更新标准
                sum1 += num;
            }
            else{
                int num = 0;
                while(i <= j && num <= temp1){
                    num += x[j--];
                }
                temp2 = num;   //更新标准
                sum2 += num;
            }
            movenum++;
 
        }
        cout << movenum << " " << sum1 << " " << sum2 << endl;
 
   }
   return 0;
}

题目:(E) Special Elements

题目大意:

给出 t 组数据,对于每组数据给出一个长度为 n 的数组,寻找数组中有多少个能用该数组内连续元素和表达的数。

思路:

由题意便可以想到要先预处理前缀和,记录数组中各个元素的出现次数,两层循环遍历连续元素和情况,寻找是否在数组中存在。

解题代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
const long long N = 1e10 + 7;
const int maxn = 1e6 + 5;
const long long INF = 8e18;
typedef long long ll;
#define for0(i,n) for(int i = 0;i < n;i++)
#define for1(i,n) for(int i = 1;i <= n;i++)
using namespace std;
int main()
{
   int t,n;
   cin >> t;
   while(t--){
        int num[8010] = {0},sum[8010] = {0},sign[8010] = {0};
        int total = 0;
        cin >> n;
        for1(i,n){
            int x;
            cin >> x;
            num[x]++;
            sum[i] += sum[i-1]+x;
        }
        for(int i = 1;i <= n;i++){
            for(int j = i+1;j <= n;j++){
                    int sumnow = sum[j]-sum[i-1];
                if(sumnow <= n && sign[sumnow] == 0){
                    sign[sumnow] = 1;
                    total += num[sumnow];
                }
            }
        }
        cout << total << endl;
   }
   return 0;
}

题目:(F) Binary String Reconstruction

题目大意:

给出 t 组数据,对于每组数据给出 a,b,c 三个数(a+b+c > 0),让你构造一个含有 a 个 “00” ,b 个 “10”或“01” ,c 个 “00” 的01串。

思路:

当 b = 0 时,那么这个01串肯定是一个全1串或者全0串;另外情况下,可根据 b 构造一个10串(sb),构造一个含a个0的串(sa),构造一个含c个1的串(sc),然后将 sa 插到 sb 第一个元素后面的位置中,再将 sc 插到 sb 的开头,这样便可得到需要构造的01串。 

解题代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
const long long N = 1e10 + 7;
const int maxn = 1e6 + 5;
const long long INF = 8e18;
typedef long long ll;
#define for0(i,n) for(int i = 0;i < n;i++)
#define for1(i,n) for(int i = 1;i <= n;i++)
using namespace std;
int main(){
   int t;
   cin >> t;
   while(t--){
        int a,b,c;
        string sb = "";
        cin >> a >> b >> c;
        if(b == 0){
            if(a){
               for1(i,a+1)  cout << '0';
               cout << endl;
            }
            else{
               for1(i,c+1)  cout << '1';
               cout << endl;
            }
            continue;
 
        }
        else{
            for(int i = 0;i <= b;i++){
                if(i % 2 == 0)
                    sb += '1';
                else
                    sb += '0';
            }
            string sa(a,'0');
            string sc(c,'1');
            sb.insert(1,sa);
            sb.insert(0,sc);
        }
        cout << sb << endl;
    }
    return 0;
}

题目:(G) Special Permutation

题目大意:

给出 t 组数据,对于每组数据给出一个 n ,要求将 1~n 重新排列 构造出一个符合 ≤ pi − pi+1 ≤ 4的数列,若遇到不能构造出符合条件的情况,输出-1.

思路:

很容易想到,当 n 小于 4 时,是无法构造的;n >= 4 时,可以想到两个相邻奇数或偶数的差是2,所以只需要从最靠近 n 的奇数 一直输出到 1 然后再输出偶数,注意此时需要先输出 4 再输出 2,然后就可以从6开始依次输出递增的相邻偶数。

解题代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
const long long N = 1e10 + 7;
const int maxn = 1e6 + 5;
const long long INF = 8e18;
typedef long long ll;
#define for0(i,n) for(int i = 0;i < n;i++)
#define for1(i,n) for(int i = 1;i <= n;i++)
using namespace std;
int main()
{
   int t;
   cin >> t;
   while(t--){
        int n,num;
        cin >> n;
        if(n < 4){
            cout << -1 << endl;
            continue;
        }
        if(n % 2 == 0)
            num = n-1;
        else
            num = n;
        while(num > 0){
            cout << num << " ";
            num -= 2;
        }
        cout << "4 2";
        num = 6;
        while(num <= n){
            cout << " " << num;
            num += 2;
        }
        cout << endl;
   }
   return 0;
}