zoukankan      html  css  js  c++  java
  • codeforces good bye 2018

    codeforces good bye 2018

    good bye candidate master

    2018年的最后一场cf

    感觉打完我又用rating换了一大波rp

    T1

    题意: 给出三个数(r)(b)(y),定义(a)(b)(c)是分别小于等于这三个数且满足(a+2==b+1=c)

    (a+b+c)的最大值

    题解: 日常读错题,zz的我考场上没看清楚题面以为是要求(a>b>c),样例没测就交了。。。WA*1

    实际上只要枚举一下(a)(b)(c)那个取了最大值就好了,,,要满足答案最大,一定有一个是取最大值的

    代码:

    #include<map>
    #include<queue>
    #include<cmath>
    #include<bitset>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int a,b,c;
    int main(){
    //	freopen("1.in","r",stdin);
    	scanf("%d%d%d",&a,&b,&c);
    	if(a+1<=b&&a+2<=c) printf("%d
    ",3*a+3);
    	else
    	if(b<=a+1&&b+1<=c) printf("%d
    ",3*b);
    	else
    	printf("%d
    ",3*c-3);
    	return 0;
    }
    
    

    T2

    题意:给出(n)个标志物坐标((x_i,y_i))以及(n)个线索((a_i,b_i)),要把标志物和线索两两匹配使得所有((x_i+a[p_i],y_i+a[y_i]))相等

    题解:本来是想要先枚举第一个坐标所匹配的线索,然后判断是否存在匹配方案使得宝藏坐标等于枚举出的坐标,这样时间复杂度(n^2logn)应该也能过,虽然有点zz

    然而其实这道题可以(nlogn)过:要想每个都相等,对于最小的(x)坐标,一定要给他最大的(a)来补,对于(y)也是一样。。

    这样的话sort一遍就好了

    代码:

    #include<map>
    #include<queue>
    #include<cmath>
    #include<bitset>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=1100;
    struct node{
    	int x,y;
    }e[maxn],t[maxn];
    int n;
    bool cmp(node x,node y){return x.x<y.x;}
    bool Cmp(node x,node y){return x.y<y.y;}
    int main(){
    //	freopen("1.in","r",stdin);
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		scanf("%d%d",&e[i].x,&e[i].y);
    	for(int i=1;i<=n;i++)
    		scanf("%d%d",&t[i].x,&t[i].y);
    	sort(e+1,e+n+1,cmp);
    	sort(t+1,t+n+1,cmp);
    	printf("%d ",e[1].x+t[n].x);
    	sort(e+1,e+n+1,Cmp);
    	sort(t+1,t+n+1,Cmp);
    	printf("%d
    ",e[1].y+t[n].y);
    	return 0;
    }
    
    

    T3

    题意:n个元素的环,编号为1~n,一个球一开始在1,每次可以顺时针移动k步,每移动到一个点上就会产生这个点的编号点贡献,再次到1时停止,问对于所有k,能产生哪几种不同的总贡献

    题解:对于n的每一个约数都统计一下就好了,不要忘记去重

    代码:

    #include<map>
    #include<queue>
    #include<cmath>
    #include<bitset>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=1e7+100;
    int n,tot;
    ll p[maxn];
    inline int work(int n,int x){
    	ll tmp=n/x;
    	p[++tot]=n*(tmp-1)/2+tmp;
    }
    int main(){
    //	freopen("1.in","r",stdin);
    	scanf("%d",&n);
    	for(int i=1;i*i<=n;i++)
    		if(n%i==0){
    			work(n,i),work(n,n/i); 
    		}
    	sort(p+1,p+tot+1);p[0]=-1;
    	for(int i=1;i<=tot;i++)
    		if(p[i]!=p[i-1]) printf("%I64d ",p[i]);
    	printf("
    ");
    	return 0;
    }
    
    

    T4

    题意:把n个元素的所有排列按字典序头尾相接,形成一个长为(n*n!)的数列a,问有多少对(l,r)满足

    [a[l]+a[l+1]+...+a[r-1]+a[r]=n*(n+1)/2 ]

    题解:分析了一下样例,很显然的可以发现只有当(l,r)代表的是一个排列的时候才会等于(n*(n+1)/2),就考虑对于每个排列,他对答案的贡献

    想象对于每个答案排列,他都可以分为两部分,一部分属于(a)中的前一个排列末尾,一个属于后一个排列开头,因为排列总数是(n!),对于一个排列分法有(n)种,所以总方案应是(n*n!)

    但是这些方案中有一些是不合法的,比如:(n=5,设(x)是前一个末尾,y是后一个开头)

    [x={4,2},y={1,3,5} ]

    显然,完整的前一个应该是({1,3,5,4,2}),但是我们发现,后一个是不会合法的,因为他要满足比前一个大,但是前一个的最后两位(即(x))是单减的,也就是说没有比(x)大的了。

    那么我们枚举所有长度的单减序列,长度为(i)的单减序列总数就等于在一个({n,n-1,n-2,...,1})的序列里挑(i)个数,即(C(n,i)),对于每个单减序列(x),他的(y)是可以随便填的(这里的x,y还是上面的定义),方案总数((n-i)!)

    然后就没有然后了,总方案数(n*n!),不合法方案数(sum_{i=1}^n{C(n,i)*(n-i)!}),合法方案就是:

    [ans=n*n!-sum_{i=1}^n{C(n,i)*(n-i)!} ]

    如果你没有和zz的nianheng一样在手算时zz地把(4!)算成(16),你就能马上A掉这道题了

    代码:

    #include<map>
    #include<queue>
    #include<cmath>
    #include<bitset>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=1e7+100,P=998244353;
    int n;
    ll jc[maxn],ans;
    void ycl(){
    	jc[0]=1;
    	for(int i=1;i<=n;i++)
    		jc[i]=jc[i-1]*i%P;
    }
    inline ll poww(ll x,ll y){
    	ll base=1;
    	while(y){
    		if(y&1) base=base*x%P;
    		x=x*x%P;
    		y>>=1;
    	}
    	return base;
    }
    inline ll C(int n,int m){
    	return jc[n]*poww(jc[m],P-2)%P*poww(jc[n-m],P-2)%P;
    }
    int main(){
    //	freopen("1.in","r",stdin);
    	scanf("%d",&n);
    	ycl();
    	for(int i=1;i<=n;i++)
    		ans=(ans+C(n,i)*jc[n-i]%P)%P;
    	ans=(jc[n]*n%P-ans)%P;
    	printf("%I64d
    ",(ans+1)%P);
    	return 0;
    }
    
    

    感想

    失误辣么多,我还是太蒻了啊

  • 相关阅读:
    C# 内存映射研究学习
    js Promise async await 学习研究
    js 字节数组转数字以及数字转字节数组
    C# 生成一个当前程序唯一的短字符串
    C# FileStream 读取大文件时ReadByte和Read的速度对比
    用一个数维护最多32个可叠加状态,比如权限的状态,既有“读”,又有“写”
    大牛干货:100条Unity基础小贴士
    Unity教程之-Unity3d移动平台性能优化专题(12):面板的设置
    Unity ShaderLab学习总结
    (转)【Unity技巧】Unity中的优化技术
  • 原文地址:https://www.cnblogs.com/nianheng/p/10201266.html
Copyright © 2011-2022 走看看