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\n",abs(b-a)/2);
else
printf("%lld\n",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",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('\n');
}
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('\n');
}
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('\n');
}
}
}
}t;
int main(){
t.run();
return 0;
}
D.Problem Scores
回头再补
原文地址:https://www.cnblogs.com/diorvh/p/12124063.html