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

A - Remove a Progression

已经删除了 i − 1 i-1 i1个,现在要删其后的第 i i i个,因为第 i i i个在前面 i − 1 i-1 i1个之后,所以是总的第 2 i − 1 2i-1 2i1个。所以所有的奇数都会被删除。

    #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 . l e n g t h ( ) 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赢。对于 K K K,如果 K K K 3 3 3的倍数,那么因为第 K K K个元素胜利,所以后面的 1 , 2 , 3 1,2,3 1,2,3胜败重新排布,直到再次为 K K K的倍数。

    #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暴力记录判断公共相交情况,两根线之间插入 N N N根垂直的线的贡献为 N ( N − 1 ) 2 \frac{N(N-1)}{2} 2N(N1)。非常暴力的做法,复杂度为 O ( ( N 2 ) 2 N 64 ) = O ( 2 − 8 N 3 ) O((\frac{N}{2})^2\frac{N}{64}) = O(2^{-8}N^3) O((2N)264N)=O(28N3)。我给别人讲了做法,结果我太久没写反而没写出来,疯狂自闭= =

    #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

考虑失败的次数,其为二项分布。这样在前 i i i次尝试中失败次数小于等于 m m m的期望为
E i ( K ⩽ m ) = P i ( K ⩽ m ) = 1 2 i ∑ k = 0 m ( i k ) E_{i}(K\leqslant m) = P_i(K\leqslant m) = \frac{1}{2^i} \sum_{k=0}^m\binom{i}{k} Ei(Km)=Pi(Km)=2i1k=0m(ki)
由公式 C ( n , m ) = C ( n − 1 , m − 1 ) + C ( n − 1 , m ) C(n,m) = C(n-1,m-1)+C(n-1,m) C(n,m)=C(n1,m1)+C(n1,m),有
P i ( K ⩽ m ) = P i − 1 ( K ⩽ m − 1 ) + 1 2 i ( i − 1 m ) P_i(K\leqslant m) = P_{i-1}(K\leqslant m - 1)+\frac{1}{2^{i}}\binom{i-1}{m} Pi(Km)=Pi1(Km1)+2i1(mi1)
因为需要考虑的 m ⩽ n m \leqslant n mn,所以暴力反推前缀和的次数小于等于 n n n,所以总的复杂度为 O ( 2 n + log ⁡ n + n + n ) = O ( n ) O(2n+\log n + n +n) = O(n) O(2n+logn+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;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值