Codeforces 1194A 1194B 1194C 1194D 1194E 1194F

A - Remove a Progression

已經刪除了i1i-1個,現在要刪其後的第ii個,因爲第ii個在前面i1i-1個之後,所以是總的第2i12i-1個。所以所有的奇數都會被刪除。

    #include <cstdio>
    int deprec[50000];
    int main() {
        int t;
        scanf("%d",&t);
        while(t--) {
            int n, x;
            scanf("%d%d",&n,&x);
            printf("%d\n", x<<1);
        }
    }

B - Yet Another Crosses Problem

暴力記錄。。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<string> owo;
int row[500000], col[500000];
int main() {
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
            string x;
    while(t--) {
        owo.clear();
        int n,m;
        cin>>n>>m;
        fill(row, row+n+1, 0);
        fill(col, col+m+1, 0);
        for(int i = 0; i < n; i++) {
            cin>>x;
            for(int j = 0; j < m; j++) {
                if(x[j]=='*') {
                    row[i]++;
                    col[j]++;
                }
            }
            owo.emplace_back(x);
        }
        int ret = n + m -1;
        for(int i = 0; i < n;i++) {
            for(int j=0;j<m;j++){
                ret = min(ret, n +m-1 - row[i] - col[j] +(owo[i][j]=='*'));
                // printf("%d %d %d\n",  n +m-1 , owo[i][j]=='*',  - row[i] - col[j] );
            }
            // puts("");
        }
        cout<<ret<<'\n';
    }
}

C - From S To T

暴力插入,需要特別判斷第a.length()a.length()以後的情況。

    #include <iostream>
    #include <string>
    using namespace std;
    string a,b,c;
    int f[28];
    int main() {
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        // cout << 'z' - 'a';
        while(t--) {
            for (int i=0; i < 26; i++) {
                f[i] = 0;
            }
            cin>>a>>b>>c;
            
            if (a== b){
                cout << "YES\n";
                continue;
            }
            if (a.length() > b.length() || a.length() + c.length() < b.length()) {
                cout << "NO\n";
                continue;
            }
            
            for(unsigned int i = 0; i< c.length(); i ++) {
                f[c[i] - 'a']++;
            }
            bool flag = 1;unsigned int shif = 0;
            for(unsigned int i = 0; i < b.length() + 1; i++) {
                //cout << i - shif << i << endl;
                if (i - shif == a.length()) {
                    while(i < b.length()) {
                        if (!f[b[i]-'a']) {
                            flag = 0;
                            break;
                        }
                        f[b[i] - 'a']--;
                        i++;
                    }
                    break;
                }
                if (i == b.length()) {
                    if (a.length() + shif != b.length()) {
                        flag = 0;
                        
                    }
                    break;
                }
                if (a[i-shif] != b[i]) {
                    // printf("orz a[%c, b[%c\n",a[i-shif],b[i]);
                    if (!f[b[i]-'a']) {
                        flag = 0;
                        break;
                    }
                    shif++;
                    f[b[i] - 'a']--;
                }
            }
            cout << (flag ? "YES\n":"NO\n");
        }
    }

D - 1-2-K Game

對於1-2的情況,是普通的情況,三的倍數爲Bob贏。對於KK,如果KK33的倍數,那麼因爲第KK個元素勝利,所以後面的1,2,31,2,3勝敗重新排布,直到再次爲KK的倍數。

    #include <iostream>
    using namespace std;
    int main() {
    	int t;
    	cin>>t;
    	while(t--) {
            int n,m;
    		cin >> n >> m;
    		if(m%3 == 0) {
    			n%=(m+1);
    			if (n==0) {
    				cout<<"Bob"<<endl;
                    continue;
    			} else if (n==m) {
    				cout<<"Alice"<<endl;
                    continue;
    			}
    		}
            cout<<(n%3==0?"Bob":"Alice")<<endl;
    	}
    	return 0;
    }

E - Count The Rectangles

用BitSet暴力記錄判斷公共相交情況,兩根線之間插入NN根垂直的線的貢獻爲N(N1)2\frac{N(N-1)}{2}。非常暴力的做法,複雜度爲O((N2)2N64)=O(28N3)O((\frac{N}{2})^2\frac{N}{64}) = O(2^{-8}N^3)。我給別人講了做法,結果我太久沒寫反而沒寫出來,瘋狂自閉= =

    #include <cstdio>
    #include <bitset>
    #include <algorithm>
    #include <iostream>
    #include <vector>
    #include <utility>
    using namespace std;
    int a[5];
    bitset<5005> s[5005];
    inline bool between(int a,int b,int c) {
    	return c<=b&&c>=a;
    }
    struct node {
        int a1,b1,a2, b2;
     
        friend bool inx(node&x,node&y) {
    		if(x.a1==x.a2&&y.b1==y.b2) {
    			return between(x.b1,x.b2,y.b1)&&between(y.a1,y.a2,x.a1);
    		} else if(y.a1==y.a2&&x.b1==x.b2) {
    			return between(y.b1,y.b2,x.b1)&&between(x.a1,x.a2,y.a1);
    		}
            return false;
    	}
    };
    vector<node> va,vb;
    int main() {
        int n;
        scanf("%d",&n);
        for(int i = 0 ; i< n; i++){
            scanf("%d%d%d%d", &a[0],&a[1],&a[2],&a[3]);
            if(a[0]==a[2]) {
                if(a[1] > a[3]) {
                    swap(a[1], a[3]);
                }
            node x = {a[0],a[1],a[2],a[3]};
                va.emplace_back(x);
            } else {
                if(a[0] > a[2]) {
                    swap(a[0], a[2]);
                }   
            node x = {a[0],a[1],a[2],a[3]};
                vb.emplace_back(x);
            }
            //     cout << a[0] << " "<< a[1] << " " << a[2] << " " << a[3] << " " << endl;
        }
        // cout << va.size() << " " << vb.size();
        if (va.size() > vb.size()) va.swap(vb);
        // for(int i = 1; i <=10000;i++) {
        //     b[i] += b[i-1];
        // }
        long long ret =0;
        for(unsigned int i = 0; i < va.size();i++) {
            //printf("%d %d %d %d", va[i].a1, va[i].a2,)
            for(unsigned int j = 0; j < vb.size();j++) {
                if(inx(va[i],vb[j]))s[i][j]=true;
            }
            for(unsigned int j=0; j<i; j++) {
    			long long res=(s[i]&s[j]).count();
    			ret+=(res)*(res-1)/2;
    		}
        }
        cout << ret;
    }

F - Crossword Expert

考慮失敗的次數,其爲二項分佈。這樣在前ii次嘗試中失敗次數小於等於mm的期望爲
Ei(Km)=Pi(Km)=12ik=0m(ik) E_{i}(K\leqslant m) = P_i(K\leqslant m) = \frac{1}{2^i} \sum_{k=0}^m\binom{i}{k}
由公式C(n,m)=C(n1,m1)+C(n1,m)C(n,m) = C(n-1,m-1)+C(n-1,m),有
Pi(Km)=Pi1(Km1)+12i(i1m) P_i(K\leqslant m) = P_{i-1}(K\leqslant m - 1)+\frac{1}{2^{i}}\binom{i-1}{m}
因爲需要考慮的mnm \leqslant n,所以暴力反推前綴和的次數小於等於nn,所以總的複雜度爲O(2n+logn+n+n)=O(n)O(2n+\log n + n +n) = O(n)

    #include <iostream>
    #include<algorithm>
    using namespace std;
    long long fac[200005],invf[200005];
    long long mod = 1e9+7;
    long long qp(long long a, long long b) {
        long long res= 1;
        while(b) {
            if (b &1) res = res * a%mod ;
            a = a * a % mod; b>>=1;
        }
        return res;
    }
    long long n =200005;
    void init() {
        fac[0]=1;
        for (int i = 1; i <=n ; i ++) {
            fac[i]  =fac[i-1] *i%mod;
        }
        invf[n] = qp(fac[n], mod-2);
        for (int i = n-1;i>=0;i--) {
            invf[i] = invf[i+1] *(i+1)%mod;
        }
    }
    long long t;
     
    long long C(long long n, long long m) {
        if (n < m || n < 0 || m < 0) return 0;
        return ((fac[n]*invf[m])%mod)*invf[n-m]%mod;
    }
     
    int main() {
        init();
        long long T;
        ios::sync_with_stdio(false);
        cin>>n>>T;
        long long prefix_num=0,prefix=1;
        long long ret= 0, inv2 = invf[2];
     
        // prefix[i+1][num+1] = 2prefix[i][num] + C(n, num+1)
        for(int i  =1;i<=n;i++){
            cin>>t;
            // j = i + 1;
            prefix = (prefix * 2 + C(i-1,prefix_num+1))%mod;
            prefix_num++;
     
            T-=t;
            while(prefix_num >= 0 && T < prefix_num) {
                
                prefix += (mod- C(i,prefix_num))%mod;
                prefix %= mod;
                prefix_num --;
            }
            if (prefix_num < 0) {
                break;
            }
            ret= (ret + inv2 * prefix %mod) % mod;
            inv2 = inv2 * invf[2] % mod;
        }
        cout << ret;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章