zoukankan      html  css  js  c++  java
  • 2020hdu多校第五场比赛及补题

    1009 Paperfolding

    把一张矩形纸折n次,每次折可以从上往下折,或从下往上折,或从左往右折,或从右往左折

    这样一共有4^n种折法,折好后再把纸横切一刀,竖切一刀,再把纸展开,问展开后期望是多少张纸

    看起来好难的一题,比赛刚开始的时候,我还没读完题时,旁边的人都开始折纸了,我想:这题真的要动手折纸吗?然而我开始分析的时候,就忍不住开始折纸了2333

    分析出来后就不难了

    分析:

    • 从上往下折等价于从下往上折,从左往右折等价于从右往左折,自己拿张纸折几下,靠直觉得出这个结论
    • 自己折折纸,可以发现从左往右折a次,从上往下折b次,最后展开是((1<<a)+1)*((1<<b)+1)张纸(我找的规律,没去证明,就感觉是这样)

    计算:

    一共2^n种折法,分母就是2^n,

    从左往右一共折a次,从上往下一共折n-a次的情况是C(n,a)种(我还不会打数学符号啊啊啊),贡献为C(n,a)*((1<<a)+1)*((1<<(n-a))+1)

    检验一下,a的范围是0到n,C(n,0)+C(n,1)+C(n,2)+...+C(n,n)= 2^n种

    分子就是把C(n,a)*((1<<a)+1)*((1<<(n-a))+1)累加起来(a从0到n)

    C(n,a)*((1<<a)+1)*((1<<(n-a))+1) =       C(n,a) * [  (1<<n) + (1<<a) + (1<<(n-a)) + 1] = [C(n,a)*(1<<n)] + [C(n,a)*(1<<a)] + [C(n,a)*(1<<(n-a))] + [C(n,a)]

    [C(n,a)*(1<<n)] 累加起来等于 4^n,除以分母后等于 2^n

    [C(n,a)*(1<<a)]累加起来等于(2+1)^n = 3^n,除以分母后等于 3^n * inv(2^n)

    [C(n,a)*(1<<(n-a))]累加起来,根据对称性,它等于[C(n,a)*(1<<a)]

    [C(n,a)]累加起来等于2^n ,除以分母后等于1

    #include<iostream>
    #include<algorithm>
    using namespace std;
    const long long MOD = 998244353;
    long long qpow(long long n, long long p) {
        long long ret = 1;
        for (; p; p >>= 1, n = n * n % MOD)
            if (p & 1)
                ret = ret * n % MOD;
        return ret;
    }
    long long inv(long long a) {
        return qpow(a, MOD - 2);
    }
    int main()
    {
        int T;
        long long n;
        cin>>T;
        while(T--){
            scanf("%lld",&n);
            long long res, tt, ni;
            res = qpow(2,n);
            tt = 2*qpow(3,n);
            ni = inv(res);
            tt = tt * ni % MOD;
            res += tt + 1;
            res %= MOD;
            printf("%lld\n",res);
        }
        return 0;
    }
    

      

    1001 Tetrahedron

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    const int MAXN = 6e6 + 7;
    const int MOD = 998244353;
    // const int INF = ;
    // const int DIRX[] = {};
    // const int DIRY[] = {};
    
    int ept[MAXN];
    
    inline int getpow(int a, int b)
    {
        int ret = 1;
        for (; b; b >>= 1, a = a * a % MOD)
            if (b & 1)
                ret = ret * a % MOD;
        return ret;
    }
    
    void pre()
    {
        int tmp = 0;
        for (int i = 1; i <= 6e6; ++i)
        {
            tmp += getpow(i * i % MOD, MOD - 2);
            tmp %= MOD;
            ept[i] = tmp;
        }
    }
    
    int T;
    int n;
    int ans;
    
    int32_t main(void)
    {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        pre();
        cin >> T;
        while (T--)
        {
            cin >> n;
            ans = (3 * ept[n] % MOD) * getpow(n, MOD - 2) % MOD;
            cout << ans << endl;
        }
        return 0;
    }
    

      

    1003 Boring Game

    很恶心的一题,折叠3次的情况我根本画不出,这题耗了很长时间,差不多3小时的时候,大家都A不出题,这时突然有个队大叫A了!A了!然后我马上看下榜单,并没有什么变化,学长问他们哪题A了,他们说样例A了...xswl

    关键是模拟构造order数组,折2次及以上是有构造规律的,折1次的情况是特判

    #include<iostream>
    #include<algorithm>
    #include<cstdio> 
    using namespace std;
    int zheng[203][2050];
    int fan[203][2050];
    int order[2050],neworder[2050];
    int main()
    {
    	int T,n,k,cnt;
    	cin>>T;
    	while(T--){
    		cin>>n>>k;
    		cnt = 0;
    		for(int i = (1<<k);i;i--){
    			order[i] = 0;
    			cnt++;
    			if(i % 2) {//正 
    				for(int j = 1;j <= n;j++){
    					scanf("%d%d",&zheng[j][cnt],&fan[j][cnt]);
    				}
    			}
    			else{//反 
    				for(int j = n;j ;j--){
    					scanf("%d%d",&fan[j][cnt],&zheng[j][cnt]);
    				}
    			}
    		}
    		int len = 2;
    		order[1] = 1 ;order[2] = 2;//折2次的情况把折1次的情况包括进去了,初始化就直接初始成折2次的情况 
    		for(int e = 2;e <= k;e++){//从折2次开始构造 
    			for(int i = 1;i<=len;i++){
    				int x = order[len-i+1];
    				if(x%2) neworder[i] = x * 2;
    				else neworder[i] = x * 2 - 1; 
    			}
    			for(int i = len+1;i<=len*2;i++){
    				int x = order[i-len];
    				if(x%2) neworder[i] = x * 2 - 1;
    				else neworder[i] = x * 2;
    			}
    			len *= 2;
    			for(int i = 1;i <= len;i++){
    				order[i] = neworder[i];
    				//cout<<order[i]<<" ";
    			}
    			//cout<<endl;
    		}
    		for(int i = 1;i<=n;i++){
    			for(int j = 1;j <= (1<<k) ;j++){
    				printf("%d ",zheng[i][order[j]]);
    			}
    			//printf("\n");
    			for(int j = 1;j < (1<<k) ;j++){
    				printf("%d ",fan[i][order[j]]);
    			}
    			printf("%d",fan[i][order[(1<<k)]]);
    			if(i!=n) printf(" ");	
    			//printf("\n");
    		}
    		printf("\n");
    	}
    	return 0;
    }
    

      

    PE了2发,惊了,末尾多输出空格会PE

    1012 Set1

    一个集合为1,2,3,4,...,n ,n是奇数,每次操作是集合中会删掉一个最小的数,然后随机选一个数删除,重复进行这集合个操作直到集合中只剩下最后一个数

    求1,2,3....分别为最后一个数的概率

    分母 = 总的操作方案数 = (n-1)*(n-3)*(n-5)*...*2 = ((n-1)/2)! * 2^((n-1)/2)

    1,2,3,...(n-1)/2是不可能成为最后一个数的

    第 i 个数,在其后 n - i 个数必须要删完,也就是分子 = (n-i)! * 某个东西

    比赛的时候就是这个某个东西算不来

    关键的一点就是,在删这n - i个数中的某个数a时,在前 i - 1个数中删掉了剩余的最小的数b,这n - i 个a对应n - i个b,而这n - i 个 b 可以是前 i - 1个数里选出的 n - i 个数的任意组合,情况有C(i - 1,n - i)种,这 n - i 个 b确定后,前 i - 1 个数里剩下的数就可以任意删了

    假设剩下的数有 re 个,任意删的方案数 = (n-1)*(n-3)*(n-5)*...*1 = (n-1)! / [(n-2)*(n-4)*...*2] = (n-1)! / { [(n-2)/2]! * 2^[(n-2)/2] } 

    某个东西 = C(i - 1,n - i) * (n - 1)! / { [(n-2)/2]! * 2^[(n-2)/2] } 

    主要就是没想到后n - i 个数对应前 i - 1个数中 n - i个数

    #include<iostream>
    #include<algorithm> 
    using namespace std;
    const int MAXN = 5e6+7;
    const long long MOD = 998244353; 
    long long fact[MAXN];
    long long inv[MAXN];
    void pre(){
    	fact[0] = 1;
    	for(int i = 1;i <= 5e6;i++)
    		fact[i] = fact[i-1] * i % MOD;
    	inv[1] = 1;
        for (int i = 2; i <= 5e6; i++)
            inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;
        inv[0] = 1;
        for (int i = 1; i <= 5e6; i++)
            inv[i] = inv[i] * inv[i - 1] % MOD;
    }
    
    long long qpow(long long n, long long p) {
        long long ret = 1;
        for (; p; p >>= 1, n = n * n % MOD)
            if (p & 1)
                ret = ret * n % MOD;
        return ret;
    }
    long long mod_inv(long long a){
    	return qpow(a,MOD-2);
    }
    long long C(int n,int m){
    	return fact[n]*inv[m]%MOD*inv[n-m]%MOD;
    }
    int main()
    {
    	int T, n;
    	pre();
    	cin>>T;
    	long long MODINV2 = mod_inv(2);
    	while(T--){
    		cin>>n;
    		if(n == 1) {
    			printf("1\n");
    			continue;
    		}
    		long long fm, invfm;
    		fm = qpow(2,n/2)*fact[n/2]%MOD;
    		invfm = mod_inv(fm);
    		int pos = n / 2 + 1;
    		int re = 0;
    		long long tt = 1;
    		for(int i = 1;i < pos;i++) printf("0 ");
    		for(;pos <= n;pos++){
    			long long res = fact[n-pos];
    			res = res * C(pos-1,n-pos) % MOD;
    			long long ret ;
    			if(!re) ret = 1;
    			else{
    				ret = fact[re-1] * inv[(re-2)/2] % MOD * tt % MOD;
    				tt = tt * MODINV2 % MOD;
    			}
    			res = res * ret % MOD * invfm % MOD;
    			re += 2;
    			if(pos < n)printf("%lld ",res);
    			else printf("%lld\n",res);
    		}
    	}
    	return 0;
    } 
    

      

  • 相关阅读:
    [LeetCode]2. Add Two Numbers链表相加
    Integration between Dynamics 365 and Dynamics 365 Finance and Operation
    向视图列添加自定义图标和提示信息 -- PowerApps / Dynamics365
    Update the Power Apps portals solution
    Migrate portal configuration
    Use variable to setup related components visible
    Loyalty management on Retail of Dynamic 365
    Modern Fluent UI controls in Power Apps
    Change screen size and orientation of a canvas app in Power App
    Communication Plan for Power Platform
  • 原文地址:https://www.cnblogs.com/ruanbaitql/p/13560700.html
Copyright © 2011-2022 走看看