zoukankan      html  css  js  c++  java
  • 【日记】12.28/【题解】AtCoder AGC041

    12.28

    这一天补了上次两道CF上的题目,之后写了一堆dp模板,最后打了一把AtCoder,感觉相当不错,不过也是构造题比较玄学才能过吧。

    A.Table Tennis Training

    题意:有2n个运动员,n张桌子。在x桌子上,赢的人会进入x-1,输的人会进入x+1,除了1和n桌子上的人之外、现在有两个巨强无比的人分别在A和B桌子上,可以随意控制输赢,问他们最少需要用多少轮才能在一张桌子上打。

    思路:如果AB本来就相邻,那么必须要把他俩推到一边(1或N)才可以,如果恰好差2,那么可以一赢一输放到中间。因此首先判断差值奇偶性,偶数的话直接/2就行了,如果是奇数,就看谁更靠近边缘,先让他靠边,然后再边上打一轮,把差值变成偶数,之后再靠近。注意开LL。

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define mid ((l+r)>>1)
    const int M=1e5+20,P=1e9+7;
    struct Task{
    	LL n,a,b;
    	void init(){
    		scanf("%lld%lld%lld",&n,&a,&b);
    	}
    	void run(){
    		init();
    		if ((a-b)%2==0)
    			printf("%lld
    ",abs(b-a)/2);
    		else
    			printf("%lld
    ",min(a-1,n-b)+(abs(a-b)+1)/2);
    	}
    }t;
    int main(){
    	t.run();
    	return 0;
    }
    

    B.Voting Judges

    题意:有N个问题,一开始每个问题有a[i]分数。有M个裁判,每个人都会恰好选V个问题,这些问题分数+1。最后会选择分数最高的P个问题选出来,如果有分数相同,那么chief会随机排名。现在问有多少个问题有可能被选出来?

    思路:显然满足二分性质(当然直接扫一遍也可以)。首先按a[i]从小到大排序,我们来考虑判断第i个问题是否能被选中。投票可以等价为,要添加MV,但每个问题最多增加M,增加之后第i个问题的排名要>=N-P+1。那么可以这样贪心,首先第i的问题肯定尽可能多得票,即获得M,之后再让前P-1的问题每个获得M,即n-p+2到n,再之后,由于第i个问题增加了M,那么1到i-1这些问题也可以获得M,反正加了之后又不会超过第i个问题。这样就已经分出去了(1+P-1+i-1)*M个选票。之后还剩下i+1-n-p这些问题(以k表示),他们也可以获得选票,但获得的选票最多不超过(a[i]+M-a[k]),这样保证在最后排名的时候,中间的问题不会超过第i个问题,这样第i个问题就至少排在第p位。中间那个可以用前缀和来处理。可以二分找分界点,也可以直接On扫。反正判断都是O(1)的。

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define mid ((l+r)>>1)
    const int M=3e5+20,P=1e9+7;
    struct Task{
    	LL n,m,v,p,a[M];
    	LL sum[M];
    	void init(){
    		scanf("%lld%lld%lld%lld",&n,&m,&v,&p);
    		for(int i=1;i<=n;++i)
    			scanf("%lld",&a[i]);
    	}
    	void run(){
    		init();
    		sort(a+1,a+n+1);
    		for(int i=1;i<=n;++i)
    			sum[i]=sum[i-1]+a[i];
    		LL ans=n-p;
    		while(ans>=1){
    			if(a[ans]+m<a[n-p+1])
    				break;
    			if(1LL*(ans+p-1)*m+1LL*(n-p+1-(ans+1)+1)*(a[ans]+m)-(sum[n-p+1]-sum[ans])>=1LL*v*m)
    				--ans;
    			else
    				break;
    		}
    		printf("%lld
    ",n-ans);
    	}
    }t;
    int main(){
    	t.run();
    	return 0;
    }
    

    C.Domino Quality

    题意:有一堆1*2的方块,可以横放或竖放在n×n的网格中。要求摆上去之后,每个横行和竖列出现的方块数相同。

    思路:构造题。2不存在,34567都可以搞出来,3是横竖都是2,4567横竖都是3。那么接下来用这些就可以来做了对6k+3,直接用3去拼。

    对6k,6k+4,6k+5,首先拼k个6×6,之后再添加一个4×4或5×5.

    对6k+1,6k+2,首先拼k-1个6×6,之后再添加一个7×7或两个4×4即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define mid ((l+r)>>1)
    const int M=1e3+20,P=1e9+7;
    struct Task{
    	int n;
    	char s[M][M];
    	void init(){
    		scanf("%d",&n);
    		for(int i=1;i<=n;++i)
    			for(int j=1;j<=n;++j)
    				s[i][j]='.';
    	}
    	void run(){
    		init();
    		if (n==2){
    			cout<<-1<<endl;
    			return ;
    		}
    		if (n%3==0){
    			for(int i=1;i<=n/3;++i){
    				int ca=3*(i-1);
    				s[ca+1][ca+1]=s[ca+1][ca+2]='a';
    				s[ca+1][ca+3]=s[ca+2][ca+3]='b';
    				s[ca+2][ca+1]=s[ca+3][ca+1]='c';
    				s[ca+3][ca+2]=s[ca+3][ca+3]='d';
    			}
    			for(int i=1;i<=n;++i){
    				for(int j=1;j<=n;++j)
    					putchar(s[i][j]);
    				putchar('
    ');
    			}
    			return;
    		}
    		if (n%6==0||n%6==4||n%6==5){
    			for(int i=1;i<=n/6;++i){
    				int ca=6*(i-1);
    				s[ca+1][ca+1]=s[ca+2][ca+1]='a';
    				s[ca+1][ca+4]=s[ca+2][ca+4]='b';
    				s[ca+1][ca+5]=s[ca+1][ca+6]='c';
    				s[ca+2][ca+5]=s[ca+2][ca+6]='d';
    				s[ca+3][ca+2]=s[ca+4][ca+2]='e';
    				s[ca+3][ca+3]=s[ca+3][ca+4]='f';
    				s[ca+3][ca+5]=s[ca+4][ca+5]='g';
    				s[ca+4][ca+3]=s[ca+4][ca+4]='h';
    				s[ca+5][ca+1]=s[ca+5][ca+2]='i';
    				s[ca+6][ca+1]=s[ca+6][ca+2]='j';
    				s[ca+5][ca+3]=s[ca+6][ca+3]='k';
    				s[ca+5][ca+6]=s[ca+6][ca+6]='l';
    			}
    			int ca=6*(n/6);
    			if (n%6==4){
    				s[ca+1][ca+1]=s[ca+1][ca+2]='a';
    				s[ca+2][ca+1]=s[ca+2][ca+2]='b';
    				s[ca+1][ca+3]=s[ca+2][ca+3]='c';
    				s[ca+1][ca+4]=s[ca+2][ca+4]='d';
    				s[ca+3][ca+1]=s[ca+4][ca+1]='e';
    				s[ca+3][ca+2]=s[ca+4][ca+2]='f';
    				s[ca+3][ca+3]=s[ca+3][ca+4]='g';
    				s[ca+4][ca+3]=s[ca+4][ca+4]='h';
    			}
    			if (n%6==5){
    				s[ca+1][ca+1]=s[ca+2][ca+1]='a';
    				s[ca+3][ca+1]=s[ca+4][ca+1]='b';
    				s[ca+5][ca+1]=s[ca+5][ca+2]='c';
    				s[ca+5][ca+3]=s[ca+5][ca+4]='d';
    				s[ca+5][ca+5]=s[ca+4][ca+5]='e';
    				s[ca+3][ca+5]=s[ca+2][ca+5]='f';
    				s[ca+1][ca+5]=s[ca+1][ca+4]='g';
    				s[ca+1][ca+3]=s[ca+1][ca+2]='h';
    				s[ca+2][ca+2]=s[ca+2][ca+3]='i';
    				s[ca+3][ca+4]=s[ca+4][ca+4]='j';
    			}
    			for(int i=1;i<=n;++i){
    				for(int j=1;j<=n;++j)
    					putchar(s[i][j]);
    				putchar('
    ');
    			}
    			return;
    		}
    		if (n%6==1||n%6==2){
    			for(int i=1;i<=n/6-1;++i){
    				int ca=6*(i-1);
    				s[ca+1][ca+1]=s[ca+2][ca+1]='a';
    				s[ca+1][ca+4]=s[ca+2][ca+4]='b';
    				s[ca+1][ca+5]=s[ca+1][ca+6]='c';
    				s[ca+2][ca+5]=s[ca+2][ca+6]='d';
    				s[ca+3][ca+2]=s[ca+4][ca+2]='e';
    				s[ca+3][ca+3]=s[ca+3][ca+4]='f';
    				s[ca+3][ca+5]=s[ca+4][ca+5]='g';
    				s[ca+4][ca+3]=s[ca+4][ca+4]='h';
    				s[ca+5][ca+1]=s[ca+5][ca+2]='i';
    				s[ca+6][ca+1]=s[ca+6][ca+2]='j';
    				s[ca+5][ca+3]=s[ca+6][ca+3]='k';
    				s[ca+5][ca+6]=s[ca+6][ca+6]='l';
    			}
    			int ca=6*(n/6-1);
    			if (n%6==1){
    				s[ca+1][ca+1]=s[ca+1][ca+2]='a';
    				s[ca+1][ca+3]=s[ca+1][ca+4]='b';
    				s[ca+1][ca+6]=s[ca+2][ca+6]='c';
    				s[ca+2][ca+1]=s[ca+3][ca+1]='d';
    				s[ca+4][ca+1]=s[ca+5][ca+1]='e';
    				s[ca+2][ca+2]=s[ca+2][ca+3]='f';
    				s[ca+3][ca+3]=s[ca+3][ca+4]='g';
    				s[ca+4][ca+5]=s[ca+5][ca+5]='h';
    				s[ca+6][ca+5]=s[ca+6][ca+6]='i';
    				s[ca+6][ca+2]=s[ca+7][ca+2]='j';
    				s[ca+7][ca+4]=s[ca+7][ca+5]='k';
    				s[ca+7][ca+6]=s[ca+7][ca+7]='l';
    				s[ca+3][ca+7]=s[ca+4][ca+7]='m';
    				s[ca+5][ca+7]=s[ca+6][ca+7]='n';
    			}
    			if (n%6==2){
    				s[ca+1][ca+1]=s[ca+1][ca+2]='a';
    				s[ca+2][ca+1]=s[ca+2][ca+2]='b';
    				s[ca+1][ca+3]=s[ca+2][ca+3]='c';
    				s[ca+1][ca+4]=s[ca+2][ca+4]='d';
    				s[ca+3][ca+1]=s[ca+4][ca+1]='e';
    				s[ca+3][ca+2]=s[ca+4][ca+2]='f';
    				s[ca+3][ca+3]=s[ca+3][ca+4]='g';
    				s[ca+4][ca+3]=s[ca+4][ca+4]='h';
    				ca+=4;
    				s[ca+1][ca+1]=s[ca+1][ca+2]='a';
    				s[ca+2][ca+1]=s[ca+2][ca+2]='b';
    				s[ca+1][ca+3]=s[ca+2][ca+3]='c';
    				s[ca+1][ca+4]=s[ca+2][ca+4]='d';
    				s[ca+3][ca+1]=s[ca+4][ca+1]='e';
    				s[ca+3][ca+2]=s[ca+4][ca+2]='f';
    				s[ca+3][ca+3]=s[ca+3][ca+4]='g';
    				s[ca+4][ca+3]=s[ca+4][ca+4]='h';
    			}
    			for(int i=1;i<=n;++i){
    				for(int j=1;j<=n;++j)
    					putchar(s[i][j]);
    				putchar('
    ');
    			}
    		}
    	}
    }t;
    int main(){
    	t.run();
    	return 0;
    }
    

    D.Problem Scores

    回头再补

  • 相关阅读:
    常用的DOCS命令
    [51NOD1126]求递推序列的第n项(矩阵快速幂)
    [HDOJ2830]Matrix Swapping II(胡搞)
    [每天一道A+B]签到检测程序
    [HIHO1260]String Problem I(trie树)
    [HIHO1300]展胜地的鲤鱼旗(栈,dp)
    [HIHO1299]打折机票(线段树)
    [51NOD1087]1 10 100 1000(规律,二分)
    [POJ2002]Squares(计算几何,二分)
    [HDOJ1015]Safecracker(DFS, 组合数学)
  • 原文地址:https://www.cnblogs.com/diorvh/p/12124063.html
Copyright © 2011-2022 走看看