codeforces good bye 2018
codeforces good bye 2018
good bye candidate master
2018年的最后一场cf
感觉打完我又用rating换了一大波rp
T1
题意: 给出三个数,,,定义,,是分别小于等于这三个数且满足
求的最大值
题解: 日常读错题,zz的我考场上没看清楚题面以为是要求,样例没测就交了。。。WA*1
实际上只要枚举一下,,那个取了最大值就好了,,,要满足答案最大,一定有一个是取最大值的
代码:
#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\n",3*a+3);
else
if(b<=a+1&&b+1<=c) printf("%d\n",3*b);
else
printf("%d\n",3*c-3);
return 0;
}
T2
题意:给出个标志物坐标以及个线索,要把标志物和线索两两匹配使得所有相等
题解:本来是想要先枚举第一个坐标所匹配的线索,然后判断是否存在匹配方案使得宝藏坐标等于枚举出的坐标,这样时间复杂度应该也能过,虽然有点zz
然而其实这道题可以过:要想每个都相等,对于最小的坐标,一定要给他最大的来补,对于也是一样。。
这样的话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\n",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("\n");
return 0;
}
T4
题意:把n个元素的所有排列按字典序头尾相接,形成一个长为的数列a,问有多少对满足
题解:分析了一下样例,很显然的可以发现只有当代表的是一个排列的时候才会等于,就考虑对于每个排列,他对答案的贡献
想象对于每个答案排列,他都可以分为两部分,一部分属于中的前一个排列末尾,一个属于后一个排列开头,因为排列总数是,对于一个排列分法有种,所以总方案应是
但是这些方案中有一些是不合法的,比如:(n=5,设是前一个末尾,y是后一个开头)
显然,完整的前一个应该是,但是我们发现,后一个是不会合法的,因为他要满足比前一个大,但是前一个的最后两位(即)是单减的,也就是说没有比大的了。
那么我们枚举所有长度的单减序列,长度为的单减序列总数就等于在一个的序列里挑个数,即,对于每个单减序列,他的是可以随便填的(这里的x,y还是上面的定义),方案总数
然后就没有然后了,总方案数,不合法方案数,合法方案就是:
如果你没有和zz的nianheng一样在手算时zz地把算成,你就能马上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\n",(ans+1)%P);
return 0;
}
感想
失误辣么多,我还是太蒻了啊
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】博客园携手 AI 驱动开发工具商 Chat2DB 推出联合终身会员
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 依赖注入中的 Captive Dependency
· .NET Core 对象分配(Alloc)底层原理浅谈
· 聊一聊 C#异步 任务延续的三种底层玩法
· 敏捷开发:如何高效开每日站会
· 为什么 .NET8线程池 容易引发线程饥饿
· 终于决定:把自己家的能源管理系统开源了!
· 外部H5唤起常用小程序链接规则整理
· C#实现 Winform 程序在系统托盘显示图标 & 开机自启动
· 了解 ASP.NET Core 中的中间件
· 详解:订单履约系统规划