1. 程式人生 > 實用技巧 >7.27 2020牛客暑期多校訓練營(第六場)題解及補題

7.27 2020牛客暑期多校訓練營(第六場)題解及補題

目錄

7.27 2020牛客暑期多校訓練營(第六場)題解及補題

比賽過程

只出CE兩題,1隊出5題,還是想的很多都不到位,還總是著急提交程式碼,忘記了每一次情況後代碼得略微修改,消耗罰時。

題解

B Binary Vector

題意

\(n\)

個向量線性無關。(每個向量都不屬於之前的空間)\(n\)維,一共有\(2^n\)個向量。
求線性無關的概率。

解法

\(n=1\)時:對於\(a:a,0 (2)\)
\(n=2\)時:對於\(a,b:a,b,a+b,0 (4)\)
\(n=3\)時:對於\(a,b,c:a,b,c,a+b,a+c,b+c,a+b+c,0 (8)\)

則有\(f_n=\prod_{i=0}^{n-1} \frac{2^i-1}{2^i}\)

這道題需要知道\(\frac{f_n}{f_{n-1}}=\frac{2^n-1}{2^n}\)\(f_1=\frac{1}{2}\)

程式碼

#include <bits/stdc++.h>
using namespace std;
const int N = 2e7 + 5;
const int mod = 1e9 + 7;
long long f[N];
long long p2[N];
long long a[N];
int t, n;
int main()
{
    scanf("%d", &t);
    f[1] = 500000004; p2[0] = 1;a[0] = 1;
    for (int i = 1; i < N; i++)
    {
        p2[i] = p2[i - 1] * 500000004;
        p2[i] %= mod;
        a[i] = a[i - 1] << 1;
        a[i] %= mod;
        if (i >= 2)
        {
            f[i] = f[i - 1] * (a[i] - 1);
            f[i] %= mod;
            f[i] *= p2[i];
            f[i] %= mod;
        }
    }
    for (int i = 1; i < N; i++)
    {
        f[i] ^= f[i - 1];
    }
    while (t--)
    {
        scanf("%d", &n);
        printf("%lld\n", f[n]);
    }
}

C Combination of Physics and Maths

題意

選一些行列的子矩陣,價值為\(\frac{F}{S}\)\(F\)代表矩陣值的和,\(S\)代表矩陣底部值的和。求最大價值

解法

只選擇一列就好了,從第二行開始,每一行的數字當底,正上面的所有值包括自身是\(F\)

程式碼

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <limits>
#include <list>
#include <map>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <utility>
#include <vector>
#include <cwchar>
#include <cwctype>
using namespace std;
#define IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
const int inf = 0x3f3f3f3f;
typedef long long ll;
const int maxn = 2000500;
const ll mod = 1e9 + 7;
typedef pair<int,int> pii;
const double pi = acos(-1);
int main() {
	IO;
	int T;
	cin>>T;
	while(T--) {
		int n,m;
        int a[205][205];
        int b[205];
		cin>>n>>m;
		// memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        double ans=0.0;
        for(int i=0;i<n;i++) {
            for(int j=0;j<m;j++) {
                int x;
                cin>>x;
                b[j]+=x;
                double cnt=double(b[j]/(x*1.0));
                ans=max(ans,cnt);
            }
        }
        // cout<<ans<<endl;
        cout<<fixed<<setprecision(8)<<ans<<endl;

	}

	return 0;
}

E Easy Construction

題意

給你兩個整數\(n\)\(k\)。求你用 \(1~ n\)構造一個存在$ 1~n \(長度的連續子列都能加起來之和取模\)n\(等於\)k\(,輸出能構造出來的集合,如果不能,輸出\)-1$。

解法

①n=1的情況下,k=0的情況下就是1,否則就是不能構造;

②n>1並且n&1,k=0的時候,迴圈輸出一頭一尾,最後輸出n;

③n為偶數就是,k=0的時候,最後輸出\(\frac{n}{2}\)和n。

程式碼

#include<bits/stdc++.h>
#define ll long long
using namespace std; 
int main() {
	int n,k;
	while(cin>>n>>k){
		if(n==1){
			if(k==0){
				cout<<1<<endl;
			}
			else{
				cout<<-1<<endl;
			}
		}
		else{
			if(n&1){
				if(k!=0){
					cout<<-1<<endl; 
				}
				else{
					
					for(int i=1;i<=n/2;i++){
						cout<<i<<" "<<n-i<<" ";
					}cout<<n<<endl;
				}
			}
			else{
				if(k!=n/2){
					cout<<-1<<endl;
				}
				else{
					for(int i=1;i<n/2;i++){
						cout<<i<<" "<<n-i<<" ";
					}cout<<n/2<<" "<<n<<endl;
				}
			}
		}
	}	
}

G Grid Coloring

題意

\(n*n\)的格子,\(k\)種顏色,給每一條邊染色,要求不存在一行或者一列顏色相同,不存在相同色環,各種顏色使用的數目相同。

解法

構造題

特判一下無解的情況 \(n= 1∣∣k=1∣∣2∗(n+1)∗n mod  k ! =0\)

其他情況下,每一行從左到右順序染色,從左到右對豎邊染色,從上到下執行這個過程。
這樣可以保證每一行不相同,左右相鄰兩豎邊顏色不同。這樣肯定不存在同色環和同顏色的一行。

但是這樣每一列相鄰兩邊的顏色間隔為$ 2n+1\(,也就是當滿足\)k|(2*n+1) $時,可能出現列的顏色相同。所以我們特判這種情況,當染豎直邊的時候,對於奇數行下面的豎直邊,往右迴圈一位染色。

程式碼

#include <bits/stdc++.h>
using namespace std;
const int maxn = 205;
vector<int>a[maxn],b[maxn];
int n,k;

void Print() {
    for(int i = 1;i <= n + 1;i++) {
        for(int j = 0;j < a[i].size();j++) {
            printf("%d ",a[i][j]);
        }
        printf("\n");
    }
    
    for(int i = 1;i <= n + 1;i++) {
        for(int j = 0;j < b[i].size();j++) {
            printf("%d ",b[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d",&n,&k);
        for(int i = 1;i <= n + 1;i++) {
            a[i].clear();b[i].clear();
        }
        if(n == 1 || k == 1 || 2 * (n + 1) * n % k != 0) {
            printf("-1\n");
        } else {
            int now = 0;
            for(int i = 1;i <= n + 1;i++) {
                for(int j = 1;j <= n;j++) {
                    a[i].push_back(now + 1);
                    now = (now + 1) % k;
                }
                if(i != n + 1) {
                    for(int j = 1;j <= n + 1;j++) {
                        int nex = j;
                        if((2 * n + 1) % k == 0 && (i & 1)) { 
                            nex = nex % (n + 1) + 1;
                        }
                        b[nex].push_back(now + 1);
                        now = (now + 1) % k;
                    }
                }
            }
            Print();
        }
    }
    return 0;
}

H Harmony Pairs

題意

解法

程式碼

//將內容替換成程式碼

K K-Bag

題意

解法

程式碼

//將內容替換成程式碼