文章目录

  • 前言
  • CF54A Presents
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
  • CF54B Cutting Jigsaw Puzzle
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code
  • CF54C First Digit Law
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code
  • CF54D Writing a Song
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code
  • CF54E Vacuum Сleaner
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code

前言

整场比赛的数据范围都很良心
A是水题.
B是恶心的模拟,有一点锻炼代码能力
C是很水的数数套贪心题
D是被数据范围祸害了的构造题
E是一个很适合(像我一样)的不会计算几何的人做的计算几何题,只需要基本的向量知识

CF54A Presents

Description\text{Description}Description

你有 nnn 天时间,在这 nnn 天内,在给出的 ccc 个特定日期一定会得到礼物,此外,如果连续 kkk 天没有收到礼物,就会得到礼物.
1≤k≤n≤365,1≤c≤n1\le k\le n\le365,1\le c\le n1≤k≤n≤365,1≤c≤n

Solution\text{Solution}Solution

如果 n≤1018n\le10^{18}n≤1018,那可能还会有一些细节需要处理.
但是这个垃圾数据范围,直接模拟就行了…

#include<bits/stdc++.h>
using namespace std;
#define ll long long
//#define double long double
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=2e5+100;
const int mod=1e9+7;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m,k;
int a[400];
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifn=read();k=read();m=read();for(int i=1;i<=m;i++){int x=read();a[x]=1;}int now=0,tot(0);for(int i=1;i<=n;i++){++now;//printf("i=%d now=%d\n")if(now==k||a[i]){++tot;now=0;}}printf("%d\n",tot);return 0;
}
/**/

CF54B Cutting Jigsaw Puzzle

Description\text{Description}Description

有一个 n×mn\times mn×m 的字符串矩形,你可以指定一个大小 (x,y)(x,y)(x,y),然后把矩形分割成 nx×my\dfrac{n}{x}\times \dfrac{m}{y}xn​×ym​ 个小矩形(x∣n,y∣mx|n,y|mx∣n,y∣m),若所有的小矩形(可以旋转,但不能翻转)后均互不相同,则称这种分割是合法的.
求合法 分割的方案总数以及子矩形最小的分割方案.
n,m≤20n,m\le20n,m≤20.

Solution\text{Solution}Solution

一道复杂度怎么做应该都太不可能 TLE 的模拟题.
手玩出旋转对坐标的映射关系.
分别枚举因数暴力哈希 check 即可.
时间复杂度大概是 O(n3)O(n^3)O(n3).

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
//#define double long double
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=2e5+100;
const int mod=1e9+7;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m,k;
char s[25][25];
int key=31;
struct node{char a[25][25];inline ull calc(){ull res(0);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++) res=res*key+a[i][j]-'A'+1;}return res;}
}now,pre,w[6];
map<ull,int>mp;
int mn,x,y,res,num;
bool work(int a,int b,int x,int y){//memset(now.a,0,sizeof(a));num=0;for(int i=1;i<=max(n,m);i++){for(int j=1;j<=max(n,m);j++) now.a[i][j]=0;}for(int i=1;i<=x;i++){for(int j=1;j<=y;j++){//printf("  %d %d c=%c\n",a+i-1,b+j-1,s[a+i-1][b+j-1]);now.a[i][j]=s[a+i-1][b+j-1];}}/*printf("(%d %d)\n",a,b);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++) printf("%c",now.a[i][j]?now.a[i][j]:'0');putchar('\n');}printf("calc=%llu\n",now.calc());*/if(mp[now.calc()]) return false;w[++num]=now;for(int o=1;o<=3;o++){memcpy(pre.a,now.a,sizeof(now.a));for(int i=1;i<=max(n,m);i++){for(int j=1;j<=max(n,m);j++) now.a[i][j]=0;}for(int i=1;i<=x;i++){for(int j=1;j<=y;j++){//printf("  (%d %d)-> (%d %d)\n",i,j,j,x-i+1);now.a[j][x-i+1]=pre.a[i][j];}}swap(x,y);    if(o==2||x==y){/*for(int i=1;i<=n;i++){for(int j=1;j<=m;j++) printf("%c",now.a[i][j]?now.a[i][j]:'0');putchar('\n');}printf("calc=%llu\n",now.calc());*/if(mp[now.calc()]) return false;w[++num]=now;}}for(int i=1;i<=num;i++) mp[w[i].calc()]=1;return true;
}
bool check(int x,int y){//printf("\nx=%d y=%d\n",x,y);mp.clear();for(int i=1;i<=n;i+=x){for(int j=1;j<=m;j+=y){if(!work(i,j,x,y)) return false;}}return true;
}
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifn=read();m=read();mn=2e9;for(int i=1;i<=n;i++){scanf(" %s",s[i]+1);}for(int i=1;i<=n;i++){if(n%i) continue;for(int j=1;j<=m;j++){if(m%j) continue;if(check(i,j)){++res;//printf("------------ok! (%d %d)\n",i,j);if(mn>i*j){mn=i*j;x=i;y=j;}}}}printf("%d\n%d %d\n",res,x,y);return 0;
}
/**/

CF54C First Digit Law

Description\text{Description}Description

给出 nnn 个数,然后给出 nnn 行,每行 li,ril_i,r_ili​,ri​,代表第 iii 个数在区间 [li,ri][l_i,r_i][li​,ri​] 中,求一个概率使得这 nnn 个数中有 k%k\%k% 的数是 111 开头的.
n≤1000,1≤li≤ri≤1018n\le1000,1\le l_i\le r_i\le10^{18}n≤1000,1≤li​≤ri​≤1018.

Solution\text{Solution}Solution

设 fxf_xfx​ 为 [1,x][1,x][1,x] 符合条件的数的个数,sumx=∑x=0x10isum_x=\sum_{x=0}^x 10^isumx​=∑x=0x​10i,wxw_xwx​ 为满足 10i≤x10^i\le x10i≤x 的最大的 iii.
就有:
fx=min⁡(2×10wx−1,x)−10wx+1+sumwx−1f_x=\min(2\times10^{w_x}-1,x)-10^{w_x}+1+sum_{w_x-1}fx​=min(2×10wx​−1,x)−10wx​+1+sumwx​−1​

那么第 iii 个数符合条件的概率就是 fri−fli−1ri−li+1\dfrac{f_{r_i}-f_{l_i-1}}{r_i-l_i+1}ri​−li​+1fri​​−fli​−1​​.
求出每个变量的概率之后,简单 n2n^2n2 dp即可.
细节上,注意 101810^{18}1018 乘 101010 会爆 longlong,所以求 wxw_xwx​ 判断时要乘转除.

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
//#define double long double
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=1050;
const int mod=1e9+7;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m,k;
ll sum[20],mi[20];
double dp[N][N],p[N];
ll calc(ll x){if(x==0) return 0;int o=0;while(x/mi[o]>=10) ++o;return (o?sum[o-1]:0)+min(x,2*mi[o]-1)-mi[o]+1;
}
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifmi[0]=sum[0]=1;for(int i=1;i<=18;i++){mi[i]=mi[i-1]*10;sum[i]=sum[i-1]+mi[i];}n=read();for(int i=1;i<=n;i++){ll l=read(),r=read();p[i]=1.0*(calc(r)-calc(l-1))/(r-l+1);//printf("i=%d p=%lf\n",i,p[i]);}dp[0][0]=1;for(int i=0;i<n;i++){for(int j=0;j<=i;j++){dp[i+1][j+1]+=dp[i][j]*p[i+1];dp[i+1][j]+=dp[i][j]*(1-p[i+1]);}}int k=read();double res=0.0;for(int i=(n*k+99)/100;i<=n;i++) res+=dp[n][i];printf("%.10lf",res);return 0;
}
/**/

CF54D Writing a Song

Description\text{Description}Description

要求构造一个字符串 sss,满足该串长度为 nnn,只出现字母表中前 kkk 个字母,并且在指定位置必须出现指定字符串 ppp,或者报告无解.
n≤100n\le100n≤100.

Solution\text{Solution}Solution

第一眼:毒瘤计数题…
看完题意:恶心贪心题…
看到数据范围:就这?
或许贪心构造还是可做的,但是对于这个数据范围,我们不必冒着 WA 的风险动脑.
首先 KMP 预处理一下,然后设计 dpi,jdp_{i,j}dpi,j​ 表示填到第 iii 位,匹配到 ppp 的第 jjj 位是否合法.
转移暴力在 kmp 上跳即可,这数据范围也不需要预处理加速了.
对于输出方案,dp 过程中记录一下转移路径即可.

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
//#define double long double
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=105;
const int mod=1e9+7;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m,k;
int dp[N][N],frm[N][N],id[N][N];
int p[N],jd[N];
char s[N];
void kmp(){p[1]=0;for(int i=1,j=0;i<m;i++){while(j&&s[i+1]!=s[j+1]) j=p[j];if(s[i+1]==s[j+1]) ++j;p[i+1]=j;}//for(int i=1;i<=m;i++) printf("i=%d p=%d\n",i,p[i]);return;
}
int find(int j,int id){char c='a'+id-1;while(j&&s[j+1]!=c) j=p[j];if(s[j+1]==c) ++j;return j;
}
void print(int k,int pl){if(!k) return;print(k-1,frm[k][pl]);putchar('a'+id[k][pl]-1);
}
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifn=read();k=read();scanf(" %s",s+1);m=strlen(s+1);for(int i=1;i<=n-m+1;i++) scanf("%1d",&jd[i+m-1]);kmp();dp[0][0]=1;for(int i=0;i<=n;i++){    if(jd[i]){if(!dp[i][m]){printf("No solution\n");return 0;}for(int j=0;j<m;j++) dp[i][j]=0;//dp[i][p[m]]=1;frm[i][p[m]]=dp[i][m];id[i][p[m]]=id[i][m];}else{dp[i][m]=0;}if(i==n) break;for(int j=0;j<=m;j++){if(!dp[i][j]) continue;for(int p=1;p<=k;p++){int to=find(j,p);//printf("k=%d (%d %d) -> (%d %d)\n",p,i,j,i+1,to);dp[i+1][to]=1;frm[i+1][to]=j;id[i+1][to]=p;}}}for(int i=0;i<=m;i++){if(dp[n][i]){print(n,i);return 0;}}printf("No Solution\n");return 0;
}
/**/

CF54E Vacuum Сleaner

Description\text{Description}Description

对于一个 nnn 个结点的凸包形状的吸尘器,问你这个吸尘器在清理矩形的角落时,遗留下的最小面积,可以旋转.
n≤4×104n\le 4\times10^4n≤4×104.

Solution\text{Solution}Solution

可能是入门难度的计算几何了.
不难发现最优的时候墙一定和一条边重合(可以通过画圆证明).
那么我们就暴力枚举这条边,双指针维护墙另一条边过的顶点即可.
最后把所有点翻转过来再做一次.
实现上的技巧:

  1. 寻找另一条墙边过的点可以通过判断向量在当前边上投影的大小来实现.
  2. 计算面积时用墙的三角形面积减去多边形两个顶点截出的多边形面积,这个多边形面积可以处理一个面积关于顶点叉积的前缀和再减去这两个顶点叉积求出(建议画图理解).(算出的面积 可能为负,所以要取绝对值)
  3. 墙角三角形的边长一条可以通过投影来求,另一条勾股定理即可.

具体实现建议参考代码理解.

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
//#define double long double
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=1e5+100;
const int mod=1e9+7;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m,k;
struct P{double x,y;
}p[N];
inline P operator + (P a,P b){return (P){a.x+b.x,a.y+b.y};}
inline P operator - (P a,P b){return (P){a.x-b.x,a.y-b.y};}
inline double operator * (P a,P b){return a.x*b.x+a.y*b.y;}
inline double operator ^ (P a,P b){return a.x*b.y-a.y*b.x;}
inline double dis(P a,P b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
inline double calc(double x,double y){return sqrt(x*x-y*y);}
double sum[N];
double solve(){double res=2e18;for(int i=n+1;i<=n+n;i++) p[i]=p[i-n];for(int i=2;i<=n+n;i++) sum[i]=sum[i-1]+(p[i]^p[i-1])/2;int j=1;for(int i=1;i<=n;i++){j=max(j,i+1);while(j+1<=n*2&&(p[i+1]-p[i])*(p[j+1]-p[i])>=(p[i+1]-p[i])*(p[j]-p[i])) ++j;if(j==i+1) res=0;if(j>2*n) break;double s=sum[j]-sum[i]+(p[i]^p[j])/2;double x=(p[j]-p[i])*(p[i+1]-p[i])/dis(p[i+1],p[i]);double y=calc(dis(p[i],p[j]),x);res=min(res,x*y/2-abs(s));//printf("i=%d j=%d s=%lf x=%lf y=%lf res=%lf\n",i,j,s,x,y,x*y/2-s);}return res;
}
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifn=read();for(int i=1;i<=n;i++) p[i].x=read(),p[i].y=read();double ans=solve();reverse(p+1,p+1+n);ans=min(ans,solve());printf("%.10lf\n",ans);return 0;
}
/**/

CodeForces:54相关推荐

  1. Educational Codeforces Round 54 (Rated for Div.2)

    Educational Codeforces Round 54 (Rated for Div.2) D. Edge Deletion 题意:一张n个点的无向图,保留其中k条边,使得有尽可能多的点与1的 ...

  2. Educational Codeforces Round 54

    这套题不难,但是场上数据水,导致有很多叉点 A. 因为是让求删掉一个后字典序最小,那么当a[i]>a[i+1]的时候,删掉a[i]一定最优!这个题有个叉点,当扫完一遍如果没有满足条件的,就删去最 ...

  3. Educational Codeforces Round 54 (Rated for Div. 2) D Edge Deletion (SPFA + bfs)

    题目大意:给定你一个包含n个点m条边的无向图,现在最多在图中保留k条边,问怎么删除多的边,使得图中良好的节点数最多,求出保留在图中的边的数量和编号. 良好的节点定义为:删除某条边后该点到点1的最短距离 ...

  4. Educational Codeforces Round 54 (Rated for Div. 2): D. Edge Deletion(最短路树)

    题意: 给你n个点m条边的无向图,其中1号节点是市中心,你现在最多只能保留k条边,并要求所有点到市中心的最短路尽量不变(也就是说设点i到点1的最短路为di,那么删边之后,要保证尽可能多的点,它到1的最 ...

  5. Educational Codeforces Round 54 (Rated for Div. 2): E. Vasya and a Tree(DFS+差分)

    题意: 给你一棵n个节点的树,每个点有一个权值,初始全为0,m次操作,每次三个数(v, d, x)表示只考虑以v为根的子树,将所有与v点距离小于等于d的点权值全部加上x,求所有操作完毕后,所有节点的值 ...

  6. cf Educational Codeforces Round 54 C. Meme Problem

    原题: C. Meme Problem time limit per test1 second memory limit per test256 megabytes inputstandard inp ...

  7. 构造 Codeforces Round #302 (Div. 2) B Sea and Islands

    题目传送门 1 /* 2 题意:在n^n的海洋里是否有k块陆地 3 构造算法:按奇偶性来判断,k小于等于所有点数的一半,交叉输出L/S 4 输出完k个L后,之后全部输出S:) 5 5 10 的例子可以 ...

  8. Codeforces Round #308 (Div. 2) C. Vanya and Scales dfs

    题目链接: http://codeforces.com/contest/552/problem/C 题意: 给你100个砝码,第i个砝码质量是w^i,然后问你能不能在有m的情况下,左边和右边都放砝码, ...

  9. Codeforces 494D Upgrading Array

    http://codeforces.com/contest/494/problem/D 题意:给一个数组,和一个坏质数集合,可以无数次地让1到i这些所有数字除以他们的gcd,然后要求Σf(a[i])的 ...

最新文章

  1. Bootstrap3 排版-缩略语
  2. 工作流引擎在视频网站架构中的应用
  3. java 实现二叉树操作
  4. poj 3469 Dual Core CPU 最小割
  5. Ubuntu 键盘错位解决 更改键盘布局
  6. Linux运维学习大纲
  7. 一元三次方程求解(信息学奥赛一本通-T1238)
  8. c语言 程序统计注释比例,C语言统计单词数量程序 超详解
  9. java 熔断_熔断理解 - THISISPAN - 博客园
  10. git flow 分支合并
  11. GB-T 15834-2011《标点符号用法》文档的格式问题
  12. linux系统管理员用户名为admin,Linux创建系统管理员用户
  13. 2019世界互联网大会 聚焦网络安全发展新动能新要求 最新等保测评机构名录发布10月版
  14. flex布局对行内子元素的影响
  15. html直角三角形怎么实现,直角三角形怎么画
  16. git撤销commit
  17. 打印服务进程spoolsv 导致电脑变慢
  18. R语言使用dplyr包的full_join函数基于多个字段(数据列)全连接两个dataframe、按照多列对数据进行全连接
  19. Ubuntu 20.04系统中VSCode+CMake+GTest实现C++程序自动化单元测试的详细方法
  20. 凤凰网读书频道源代码泄露漏洞

热门文章

  1. Oracle常用知识总结
  2. chromium关闭更新_Win10今年最重磅更新!Win10 2004正式版详尽体验
  3. redis查看key的过期时间_面试官:你在Redis中设置过带过期时间的Key吗?
  4. python turtle 绘图_谈一下Pycharm中关联系统Python解释器的方法
  5. mysql 批量_mysql LOAD语句批量录入数据
  6. mysql slave 1032_修复mysql slave复制1032错误
  7. Java千万数据导入mysql_java之5分钟插入千万条数据
  8. java 异步读写_Java异步与AIO
  9. c语言怎样表示运行时间,C语言运行时间
  10. mysql 精度_mysql-笔记 精度