Codeforces Round #640 (Div. 4)(A~G)

A. Sum of Round Numbers(水題)

代碼

#include <bits/stdc++.h>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod 998244353
const int mxn = (2e5 + 10) * 2;

ll ar[mxn];
ll psum[mxn];
ll pday[mxn];
vector<int> v;

int main()
{
    /* fre(); */
    ios;
    int T;
    /* scanf("%d", &T); */
    cin >> T;
    while(T --)
    {
        v.clear();
        string s;
        cin >> s;
        for(int i = 0; i < s.size(); i ++)
        {
            if(s[i] != '0')
            {
                int ct = s.size() - i - 1;
                v.push_back((s[i] - '0') * pow(10, ct));
            }
        }
        cout << v.size() << endl;
        for(auto x : v)
            cout << x << " ";
        cout << endl;
    }

    return 0;
}


B. Same Parity Summands(水題)

分析

  • 題意
  1. 給我們一個個數n問能否將它拆分爲k個奇數或偶數相加
  • 思路
  1. 首先我們在將n拆分成全奇數或偶數的時候,我們把前k-1個拆分出來的數都當成1(最下的奇數拆分成全奇數的時候)或2(最小的偶數,拆分成全偶的時候)
  2. 我們在拆分之前要先分類討論n是奇數還是偶數,對於這兩種情況我們又可進行細分討論,k是奇數還是偶數,結合n、k 的奇偶情況就可判斷拆分出的k個數數是奇數還是偶數(或者兩種情況都行),在這個假設的基礎上進行判讀就行了

代碼

#include <bits/stdc++.h>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod 998244353
const int mxn = (2e5 + 10) * 2;

ll ar[mxn];
ll psum[mxn];
ll pday[mxn];
vector<int> v;

int main()
{
    /* fre(); */
    int T;
    scanf("%d", &T);
    while(T --)
    {
        int n, k;
        scanf("%d %d", &n, &k);
        if(n % 2)
        {
            if(k % 2)
            {
                if(n >= k)
                {
                    printf("YES\n");
                    for(int i = 1; i < k; i ++)
                        printf("1 ");
                    printf("%d\n", n - k + 1);
                }
                else
                {
                    printf("NO\n");
                }
            }
            else
            {
                printf("NO\n");
            }
        }
        else
        {
            if(k % 2)
            {
                if(n >= 2 * k)
                {
                    printf("YES\n");
                    for(int i = 1; i < k; i ++)
                        printf("2 ");
                    printf("%d\n", n - 2 * k + 2);
                }
                else
                {
                    printf("NO\n");
                }

            }
            else 
            {
                if(n >= k)
                {
                    printf("YES\n");
                    for(int i = 1; i < k; i ++)
                        printf("1 ");
                    printf("%d\n", n - k + 1);
                }
                else
                {
                    printf("NO\n");
                }
            }
        }


    }

    return 0;
}


K-th Not Divisible by n(二分)

分析

  • 題意
  1. 給我們n、k,讓我們求 n的第k個不能被n整除的數是多少?
  • 思路
  1. 這一題我們用二分來求解,網上有 通過用“數學”的方法做的
  2. 對於這一題我們可以知道對於某個數n,那麼1~x之間的所有數字中能被n整除的個數爲x/n,所以不能被整出的數字個數爲:x - n / x, 有了這個結論我們在結合n、k 的取值範圍:n<=1e9,k<=1e9n<=1e9,k<=1e9,可以得出二分的上限最大比1e9 多幾個數量級,所以我們設二分的上界爲1e14,而二分的下界爲1,就行了,通過得出的結論我們不斷進行二分區間

代碼

#include <bits/stdc++.h>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod 998244353
const int mxn = (2e5 + 10) * 2;

int main()
{
    /* fre(); */
    int T;
    scanf("%d", &T);
    while(T --)
    {
        ll n, k;
        scanf("%lld %lld", &n, &k);
        ll l = 1, r = 1e12 + 10;
        ll ans = 0;
        while(l <= r)
        {
            ll mid = (l + r) >> 1;
            if(mid - mid / n >= k)
            {
                r = mid - 1;
                ans = mid;
            }
            else
            {
                l = mid + 1;
            }
        }

        printf("%lld\n", ans);
    }

    return 0;
}

D. Alice, Bob and Candies(模擬水題)

分析

  • 思路
  1. 用前綴和、後綴和預處理一下數據,按照題意進行模擬就行了

代碼

#include <bits/stdc++.h>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod 998244353
const int mxn = 2e5 + 10;

int ar[mxn];
int prf[mxn];
int suf[mxn];

int main()
{
    /* fre(); */
    int T;
    scanf("%d", &T);
    while(T --)
    {
        int n;
        scanf("%d\n", &n);
        prf[0] = suf[n + 1] = 0;
        for(int i = 1; i <= n; i ++)
            scanf("%d", &ar[i]), prf[i] = prf[i - 1] + ar[i];
        for(int i = n; i >= 1; i --)
            suf[i] = suf[i + 1] + ar[i];

        int last = 0;
        int l = 0, r = n + 1;
        int L = 1, R = n;
        int sl = 0, sr = 0;
        int fg = 0;

        while(r - l > 1)
        {
            while(fg % 2 == 0 && L + 1 < R && prf[L] - prf[l] <= last)
                L ++;

            while(fg % 2 == 1 && R - 1 > L && suf[R] - suf[r] <= last)
                R --;

            if(fg % 2 == 0) last = prf[L] - prf[l], sl += last, l = L;
            else            last = suf[R] - suf[r], sr += last, r = R;
            fg ++;
        }
        printf("%d %d %d\n", fg, sl, sr);
    }

    return 0;
}

E. Special Elements(思維)

分析

  • 題意
  1. 這一題給我們一個有n個元素的序列ar,讓我們統計符合題意的元素數量(符合題意的元素數量值的是這個元素等於ar序列的一個連續區間中元素的和,這個連續區間的元素個數要>=2)
  • 思路
  1. 這一題我們要先考慮數據範圍:n<=8000,ari<=nn<=8000,ar_i<=n,我們可以看出數據範圍還是比較多小的,我們可以考慮暴力一點的方法,
  2. 而且這一題我們可以考慮,“連續區間”這個限制條件,既然是連續我們肯定要考慮用前綴和來維護區間數據,
  3. 有了上面的一些思考,我們可以考慮用 O(n2)O(n^2)的算法暴力的求出ar中每個位置所能的產生的子區間和,在用一個桶來統計哪些區間和出現過了,之後在對ar中的n個元素進行一邊查詢(指的是:這個數在 桶 中是否出現過)就行了

代碼

#include <bits/stdc++.h>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod 998244353

const int mxn = 8005;
int ar[mxn];
int br[mxn];


int main()
{
    /* fre(); */
    int T;
    scanf("%d", &T);
    while(T --)
    {
        memset(br, 0, sizeof(br));
        int n;
        scanf("%d\n", &n);
        for(int i = 1; i <= n; i ++)
        {
            scanf("%d", &ar[i]);
            ar[i] += ar[i - 1];
        }

        for(int i = 1; i < n; i ++)
            for(int j = i + 1; j <= n; j ++)
            {
                int val = ar[j] - ar[i - 1];
                if(val < mxn) br[val] = 1;
            }
        int ans = 0;
        for(int i = 1; i <= n; i ++)
            if(br[ar[i] - ar[i - 1]]) ans ++;
        printf("%d\n", ans);
    }

    return 0;
}


F. Binary String Reconstruction(構造)

分析

  • 題意
  1. 讓我們構造一個0、1字符串,在這個字符串中:
    00子串的數量爲n1,
    01、10的子串數量爲n2
    11的子串數量爲n3
  • 思路
  1. 我覺得對於這種構造題,我們在構造的時候要按照一定的方式、順序來構造,
  2. 在這題中我們可以,先選擇構造有n1個“00”子串的字符串s(這一步構造完之後在這個字符串中有n1 + 1個0),再其次我們可以在字符串s的基礎上選擇構造有n3個“11”子串的新字符s(在原來的基礎上s中有包含了 n3+1個連續的1,s字符串形如:00011111),
  3. 有了上面的構造,使第一個和第三個條件都得到了滿足,接下來我們在已經構造出的字符串s的基礎上,考慮怎麼構造出滿足第二個條件的新字符串s吧,對於這一步有些的特殊情況我們需要進行特殊考慮,例如在3. 過程之後構造出的字符串s爲:

    s=“0000”,這樣並沒有產生第二種情況的01、10子串,而且之後我們s的末尾拼接字符的時候是先拼接‘1’,在拼接‘0’
    s=“11111”,這樣並沒有產生第二種情況的01、10子串,而且之後我們s的末尾拼接字符的時候是先拼接‘0’,在拼接‘1’
    s=“0001111”,這種情況況下已經產生了1個“01”子串,接下來我在拼接字符的時候,拼接的字符需要我們注意

代碼

#include <bits/stdc++.h>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod 998244353

const int mxn = 8005;

int main()
{
    /* fre(); */
    int T;
    scanf("%d", &T);
    while(T --)
    {
        string s;
        int a, b, c;
        scanf("%d %d %d", &a, &b, &c);
        for(int i = 0; i <= a && a; i ++)
            s += '0';
        for(int i = 0; i <= c && c; i ++)
            s += '1';
        int ct = 0;             //在目前構造的字符串s中是否已經產生的"01"
        if(min(a, c))
            ct = 1;
        b -= ct; 
        char ch1, ch2;
        if(c == 0 && a != 0)
        {
            ch1 = '1';
            ch2 = '0';
        }
        else if(c == 0 && a == 0)
        {
            ch1 = '0';
            ch2 = '1';
            b ++;
        }
        else if(c != 0 && a == 0)
        {
            ch1 = '0';
            ch2 = '1';
        }
        else if(c != 0 && a != 0)
        {
            ch1 = '0';
            ch2 = '1';
        }



        for(int i = 0; i < b && b; i ++)
        {
            if(i % 2 == 0)
                s += ch1;
            else
                s += ch2;
        }
        cout << s << endl;
    }

    return 0;
}

G Special Permutatio(構造+思維)

分析

  • 題意
  1. 然我我們重新排列一個 n個元素的排列,是這個排列相鄰元素之間的差值大於等於2,小於等於4.
  • 思路
  1. 我覺得這一題,其實就是找出一種合理的構造方法就行,至於思路我覺得就是找找規律,沒有規律自己就胡亂湊湊看,下面就說一種符合題意的構造方法(前提是 n>=4,否則的話是沒有符合題意的答案的)
  2. 假如有一個n個數了的排列,我們我們將這個n個數中的所有奇數從大到小排序作爲答案序列的前半部分,而剩下的所有偶數中,我們把2、4單獨拿出來,按4、2的順序作爲答案序列的中間部分,之後把剩下的偶數按從小到大的順序排序作爲答案序列的後半部分,例如:n = 10 -->構造得:975314268109、7、5、3、1、4、2、6、8、10

代碼

#include <bits/stdc++.h>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { freopen("A.txt", "r", stdin);}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define ll long long
#define ull unsigned long long 
#define db double
#define Pir pair<int, int>
#define PIR pair<Pir, Pir>
#define INF 0x3f3f3f3f
#define mod 998244353

const int mxn = 8005;

int main()
{
    /* fre(); */
    int T;
    scanf("%d", &T);
    while(T --)
    {
        int n;
        scanf("%d\n", &n);
        if(n < 4) 
        {
            printf("-1\n");
            continue;
        }

        for(int i = n; i >= 1; i --)
            if(i % 2)
                printf("%d ", i);

        printf("4 2 ");
        for(int i = 6; i <= n; i ++)
            if(i % 2 == 0)
                printf("%d ", i);
        printf("\n");
    }

    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章