• Educational Codeforces Round 88 (Div. 2) 题解 (ABCDE)


    https://codeforces.com/contest/1359

    A. Berland Poker

    大概就是把jokers尽可能多地给一个人,其他人平均分吧

    #include <bits/stdc++.h>
    using namespace std;
    #define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
    #define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
    int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
    const int N=200010; typedef long long ll;
    #define int ll
    int T,n,m,k;
    signed main(){
    	cin>>T;
    	while(T--){
    		cin>>n>>m>>k;
    		if(n/k>=m)cout<<m<<endl;
    		else{
    			int t=(m-n/k+k-1-1)/(k-1);
    			cout<<n/k-t<<endl;
    		}
    	}
    	return 0;
    }
    

    B. New Theatre Square

    没什么好说的,就模拟

    #include <bits/stdc++.h>
    using namespace std;
    #define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
    #define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
    int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
    const int N=200010; typedef long long ll;
    #define int ll
    int T,n,m,a,b;
    string s;
    signed main(){
    	cin>>T;
    	while(T--){
    		cin>>n>>m>>a>>b; b=min(b,2*a);
    		int ans=0;
    		repeat(i,0,n){
    			cin>>s;
    			repeat(j,0,m)
    			if(s[j]=='.'){
    				if(j!=m-1 && s[j+1]=='.'){
    					s[j+1]='*';
    					ans+=b;
    				}
    				else ans+=a;
    			}
    		}
    		cout<<ans<<endl;
    	}
    	return 0;
    }
    

    C. Mixing Water

    哭哭~,写得我整个人都不好了,最后还是放弃(赛后,double改成long double交了一下过了。。但是不保证不会fst,就先放这吧)

    初步分析,如果t比较小那就直接输出2,否则就是一个奇数,比较麻烦。如果不断+2来找答案就超时了(TLE test4),因此我直接考虑推柿子

    当然也可以二分答案(%%%猛男lzj提供的思路)

    我的解法:

    #include <bits/stdc++.h>
    using namespace std;
    #define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
    #define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
    int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
    const int N=200010; typedef long long ll;
    #define int ll
    typedef long double lf;
    int T,h,c,t;
    signed main(){
    	cin>>T;
    	while(T--){
    		cin>>h>>c>>t;
    		if(t<=(h+c)/2){cout<<2<<endl; continue;}
    		lf t2=(t-lf(h+c)/2)/(h-c);
    		lf t3=floor(1/(4*t2)-0.5);
    		int x=llround(t3),y=x+1;
    		if(abs(lf(1)/(4*x+2)-t2)<=abs(lf(1)/(4*y+2)-t2))
    			cout<<x*2+1<<endl;
    		else
    			cout<<y*2+1<<endl;
    	}
    	return 0;
    }
    

    D. Yet Another Yet Another Task

    先固定最大值,如果最大值固定(设它为 (k))那么这时候的答案就是(去掉比最大值大的数后的)最大连续子序列和减去 (k),即 (maxlimits_{(l,r)}sumlimits_{i=l}^r a[i]-k),非常好求

    所以只要for k=30 downto -30就行了,然后里面for一遍就行了

    更加猛的方法是,每次插入未插入的最小的 (a_i),线段树维护最大子序列和(考虑到有些读者没接触过就讲一下,线段树的每个节点存三个值,答案、可以向左延伸的答案、可以向右延伸的答案(区间和可能也要))当然了,这种方法在 (a_i) 范围很大的时候也适用

    #include <bits/stdc++.h>
    using namespace std;
    #define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
    #define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
    int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
    const int N=200010; typedef long long ll;
    #define int ll
    int n,a[N];
    signed main(){
    	cin>>n;
    	repeat(i,0,n)cin>>a[i];
    	int ans=0;
    	repeat_back(k,-30,30+1){
    		int now=-1e9;
    		repeat(i,0,n){
    			if(now<0)now=a[i];
    			else now+=a[i];
    			ans=max(ans,now-k);
    		}
    		repeat(i,0,n)if(a[i]==k)a[i]=-1e9;
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    

    E. Modular Stability

    搞了一会儿发现隐藏大结论,所有 (a_i) 必须能被最小值 (a_1) 整除。为什么呢?因为。。啊没想明白,不会证(更:取一个不能被 (a_1) 整除的 (a_t),再取 (x=a_t),显然 (x\%a_1\%a_t ot=0,x\%a_t\%a_1=0),证毕)

    这样的话,只要枚举 (a_1) 的值,然后计算组合数就行了。发现结论后剩下的步骤挺水的

    #include <bits/stdc++.h>
    using namespace std;
    #define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
    #define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
    int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
    const int N=200010; typedef long long ll;
    const int mod=(0?1000000007:998244353); ll mul(ll a,ll b,ll m=mod){return a*b%m;} ll qpow(ll a,ll b,ll m=mod){ll ans=1; for(;b;a=mul(a,a,m),b>>=1)if(b&1)ans=mul(ans,a,m); return ans;} ll getinv(ll v,ll m=mod){return qpow(v,m-2,m);}
    #define int ll
    int n,k;
    struct CC{
    	static const int N=500010;
    	ll fac[N],inv[N];
    	CC(){
    		fac[0]=1;
    		repeat(i,1,N)fac[i]=fac[i-1]*i%mod;
    		inv[N-1]=qpow(fac[N-1],mod-2,mod);
    		repeat_back(i,0,N-1)inv[i]=inv[i+1]*(i+1)%mod;
    	}
    	ll operator()(ll a,ll b){ //a>=b
    		if(a<b)return 0;
    		return fac[a]*inv[a-b]%mod*inv[b]%mod;
    	}
    }C;
    signed main(){
    	cin>>n>>k; int ans=0;
    	repeat(i,1,n+1){
    		(ans+=C(n/i-1,k-1))%=mod;
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    Linux下判断字符串长度
    Linux下使用xargs得到字符串作为参数进行输出、awk得到字符串作为参数进行输出
    Linux下使用xargs将多行文本转换成一行并用tr实现逗号隔开
    Linux下使用split按行数进行切割
    Maven设置snapshot无法在远程仓库下载的问题解决
    Intellij IDEA自动生成serialVersionUID
    Spring中@Value用法收集
    Http报头Accept与Content-Type的区别(转)
    Linux下Shell的for循环语句
    Shell脚本中的分号使用
  • 原文地址:https://www.cnblogs.com/axiomofchoice/p/12985014.html
Copyright © 2020-2023  润新知