2019CCPC秦皇岛自我反省&部分题解
练了一年半了,第一次打CCPC,险些把队友坑了打铁,最后也是3题危险捡了块铜。
非常水的点双连通,我居然不相信自己去相信板子,唉,结果整来整去,本来半个小时能出的题,整到了3个小时,大失误呀,不然就可以去弄其他题了,对自己的表现太失望了,给自己记一大过。然后导致了策略失误,稀里糊涂的时间久过去了,不然感觉我们队还是能再出3题的。
可惜可惜,自己的这些大赛的经验还是不足,但相信这不会成为拖累自己队伍的后腿,发现问题就要及时调整,在赛场上还是要坚信自己所想到的,不用太苛求于模板形式。
有些急躁,但心态还是挺好,下次多喝点水,急的时候就去尿尿冷静一下。
之前思维题都由鲲鲲和+1很快就想出来了,想不出来就没得法子,自己在思维上明显退步了,接下来除了算法的学习,更重要的思维也不能忘了,自己去补一补。
之后几场不知道会怎么样,未来不可想,现在犹可抓,好好把握接下来不多的时间。
Stand by,Stand by.
1004 就看是不是只包含2和5
#include<cstdio>
bool judge(int n){
while(n>){
if(n%==) n/=;
else if(n%==) n/=;
else return false;
}
return true;
}
int main(){
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
if(judge(n)) printf("No\n");
else printf("Yes\n");
}
return ;
}
签到
1006 就看每个环的贡献,就这个sb了,套了个点双的板子,发现错误没及时改。后来重现时是单组测试,所以把多组去了
#include<cstdio>
#include<stack>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e5+,M=5e5+;
const ll md=;
struct Side{
int v,ne;
Side(){}
Side(int v,int ne):v(v),ne(ne){}
}S[M<<];
Side sta[M];
int n,sn,dn,bn,tn,head[N],dfn[N],low[N],bin[N],bsi[N];
ll cf2[M];
void init(){
sn=dn=bn=tn=;
for(int i=;i<=n;i++){
head[i]=-;
dfn[i]=bin[i]=;
}
}
void add(int u,int v){
S[sn].v=v;
S[sn].ne=head[u];
head[u]=sn++;
}
void pdc(int u,int fa){
dfn[u]=low[u]=++dn;
for(int i=head[u],v;~i;i=S[i].ne){
v=S[i].v;
if(!dfn[v]){
sta[++tn]=Side(u,v);
pdc(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]){
int su,sv;
bsi[++bn]=;
while(tn){
su=sta[tn].v;sv=sta[tn].ne;
tn--;
if(su==u&&sv==v) break;
if(bin[su]!=bn){
bin[su]=bn;
bsi[bn]++;
}
if(bin[sv]!=bn){
bin[sv]=bn;
bsi[bn]++;
}
}
}
}else if(v!=fa){
low[u]=min(low[u],dfn[v]);
if(dfn[u]>dfn[v]) sta[++tn]=Side(u,v);
}
}
}
int main(){
cf2[]=;
for(int i=;i<M;i++){
cf2[i]=cf2[i-]<<;
if(cf2[i]>=md) cf2[i]%=md;
}
int t,m,u,v;
//scanf("%d",&t);
//while(t--){
scanf("%d%d",&n,&m);
init();
for(int i=;i<m;i++){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
ll ans=;
for(int i=;i<=n;i++) if(!dfn[i]) pdc(i,i);
for(int i=;i<=bn;i++){
if(!bsi[i]) continue;
ans*=((cf2[bsi[i]]-)%md+md)%md;
if(ans>=md) ans%=md;
m-=bsi[i];
}
ans*=cf2[m];
if(ans>=md) ans%=md;
printf("%lld\n",ans);
// }
return ;
}
点双
其实直接dfs找环就行了。
#include<cstdio>
#include<stack>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e5+,M=5e5+;
const ll md=;
struct Side{
int v,ne;
Side(){}
Side(int v,int ne):v(v),ne(ne){}
}S[M<<];
Side sta[M];
int n,m,sn,dn,bn,tn,head[N],vis[N],dep[N];
ll ans,cf2[M];
void init(){
sn=dn=bn=tn=;
for(int i=;i<=n;i++){
head[i]=-;
vis[i]=;
}
}
void add(int u,int v){
S[sn].v=v;
S[sn].ne=head[u];
head[u]=sn++;
}
void dfs(int u,int fa,int d){
dep[u]=d;
vis[u]=;
for(int i=head[u],v;~i;i=S[i].ne){
v=S[i].v;
if(v==fa||vis[v]==) continue;
if(vis[v]){
m-=d-dep[v]+;
ans*=(cf2[d-dep[v]+]-+md)%md;
if(ans>=md) ans%=md;
}else dfs(v,u,d+);
}
vis[u]=;
}
int main(){
cf2[]=;
for(int i=;i<M;i++){
cf2[i]=cf2[i-]<<;
if(cf2[i]>=md) cf2[i]%=md;
}
int t,u,v;
scanf("%d%d",&n,&m);
init();
for(int i=;i<m;i++){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
ans=;
for(int i=;i<=n;i++) if(!vis[i]) dfs(i,i,);
ans*=cf2[m];
if(ans>=md) ans%=md;
printf("%lld\n",ans);
return ;
}
dfs判环
1009 一道dp题,当时是+1做的,自己补了下。就每个技能最多有6种组合,dp[i][j]就是第i个技能,是用第j个组合按出来的,最少方案数。然后预处理一下,两两技能不同组合之间转移时需要多按的键数便可。
#include<cstdio>
#include<tr1/unordered_map>
#include<cstring>
#include<algorithm>
using namespace std;
const char jn[][][]={
{{"QQQ"},{"QQQ"},{"QQQ"},{"QQQ"},{"QQQ"},{"QQQ"}},
{{"QQW"},{"WQQ"},{"QWQ"},{"QQW"},{"WQQ"},{"QWQ"}},
{{"QQE"},{"EQQ"},{"QEQ"},{"QQE"},{"EQQ"},{"QEQ"}},
{{"WWW"},{"WWW"},{"WWW"},{"WWW"},{"WWW"},{"WWW"}},
{{"QWW"},{"WQW"},{"WWQ"},{"QWW"},{"WQW"},{"WWQ"}},
{{"WWE"},{"EWW"},{"WEW"},{"WWE"},{"EWW"},{"WEW"}},
{{"EEE"},{"EEE"},{"EEE"},{"EEE"},{"EEE"},{"EEE"}},
{{"QEE"},{"EQE"},{"EEQ"},{"QEE"},{"EQE"},{"EEQ"}},
{{"WEE"},{"EWE"},{"EEW"},{"WEE"},{"EWE"},{"EEW"}},
{{"QWE"},{"QEW"},{"WQE"},{"WEQ"},{"EWQ"},{"EQW"}},
};
const int N=1e5+,inf=1e9+;
int val[][][][],dp[N][];
char s[N];
tr1::unordered_map<char,int> mmp;
void init(){
mmp['Y']=;mmp['V']=;mmp['G']=;mmp['C']=;mmp['X']=;
mmp['Z']=;mmp['T']=;mmp['F']=;mmp['D']=;mmp['B']=;
for(int i=;i<;i++)
for(int j=;j<;j++)
for(int k=;k<;k++)
for(int l=;l<;l++){
for(int q=,p;q<=;q++){
for(p=q;p<;p++)
if(jn[i][k][p]!=jn[j][l][p-q]) break;
if(p>=){
val[i][j][k][l]=q;
break;
}
}
}
}
int main(){
init();
while(~scanf("%s",s)){
int lens=strlen(s);
for(int i=;i<lens;i++)
for(int j=;j<;j++) dp[i][j]=inf;
for(int i=;i<;i++) dp[][i]=;
for(int i=;i<lens;i++){
int j1=mmp[s[i-]],j2=mmp[s[i]];
for(int k1=;k1<;k1++)
for(int k2=;k2<;k2++)
dp[i][k2]=min(dp[i][k2],dp[i-][k1]+val[j1][j2][k1][k2]+);
}
int ans=inf;
for(int i=;i<;i++) ans=min(ans,dp[lens-][i]);
printf("%d\n",ans);
}
return ;
}
这就是我为什么不玩dota
1010 哎,字符串循环节水题,当时忘了,就没做这题。我们需要知道的任意长度后缀里的循环节长度是多少,那倒序求一遍kmp即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e7+;
const ll inf=1e18+;
char s1[N],s2[N];
int ne[N];
void getne(char *s){
int i=,j=-,lens=strlen(s);
ne[]=-;
while(i<lens){
if(j==-||s[i]==s[j]) ne[++i]=++j;
else j=ne[j];
}
}
int main(){
int a,b;
while(~scanf("%d%d%s",&a,&b,s1)){
int lens1=strlen(s1),lens2;
for(int i=;i<lens1;i++){
if(s1[lens1--i]=='.'){
s2[i]='\0';
break;
}
s2[i]=s1[lens1--i];
}
getne(s2);
lens2=strlen(s2);
ll ans=-inf;
for(int i=;i<=lens2;i++){
int len=i-ne[i];
ans=max(ans,1ll*a*i-1ll*b*len);
}
printf("%lld\n",ans);
}
return ;
}
我太菜了
1005 我第一道看的就是这题,当时就觉得是网络流能做,可惜当时做的人不多,就没开。干就完事了。然后因为任意两个机器人肯定不能走同样的路径,也就是每个位置的水平和垂直方向只能走一次,所以就是每个
位置抄成两个点,然后转向器无非就是在每个位置的水平和垂直的两点间连边,然后再把机器人与相应位置的水平方向连边,终点与相应位置的垂直方向连边,然后跑一遍,看最大流是不是等于机器人数就好了。
#include<cstdio>
#include<queue>
using namespace std;
const int N=2e4+,inf=1e9+;
struct Side{
int v,w,ne;
}S[N<<];
char mp[][];
int sb,se,sn,head[N],dep[N],cur[N];
void init(){
sn=;
for(int i=sb;i<=se;i++) head[i]=-;
}
void add(int u,int v,int w){
S[sn].v=v;
S[sn].w=w;
S[sn].ne=head[u];
head[u]=sn++;
}
void addE(int u,int v,int w,int op){
add(u,v,w);
add(v,u,op ? : w );
}
bool bfs(){
for(int i=sb;i<=se;i++) dep[i]=;
queue<int> q;
dep[sb]=;
q.push(sb);
int u,v;
while(!q.empty()){
u=q.front();
q.pop();
for(int i=head[u];~i;i=S[i].ne){
v=S[i].v;
if(S[i].w>&&!dep[v]){
dep[v]=dep[u]+;
if(v==se) return true;
q.push(v);
}
}
}
return false;
}
int dfs(int u,int minf){
if(!minf||u==se) return minf;
int v,flow;
for(int &i=cur[u];~i;i=S[i].ne){
v=S[i].v;
if(S[i].w>&&dep[v]==dep[u]+){
flow=dfs(v,min(minf,S[i].w));
if(flow){
S[i].w-=flow;
S[i^].w+=flow;
return flow;
}
}
}
return ;
}
int dinic(){
int maxf=,flow;
while(bfs()){
for(int i=sb;i<=se;i++) cur[i]=head[i];
while(flow=dfs(sb,inf)) maxf+=flow;
}
return maxf;
}
int main(){
int t,n,m,a,b,x;
scanf("%d",&t);
while(t--){
scanf("%d%d%d%d",&n,&m,&a,&b);
sb=;se=*n*m+;
init();
for(int i=;i<n;i++){
scanf("%s",mp[i]);
for(int j=;j<m;j++){
//printf("%d %d\n",i*m+j+1,n*m+i*m+j+1);
if(mp[i][j]=='') continue;
addE(i*m+j+,n*m+i*m+j+,,);
if(i&&mp[i-][j]!='') addE(i*m+j+,(i-)*m+j+,,);
if(j&&mp[i][j-]!='') addE(n*m+i*m+j+,n*m+i*m+j,,);
}
}
for(int i=;i<=a;i++){
scanf("%d",&x);
if(mp[][x-]!='') addE(sb,x,,);
}
for(int i=;i<=b;i++){
scanf("%d",&x);
if(mp[n-][x-]!='') addE((n-)*m+x,se,,);
}
if(dinic()!=a) printf("No\n");
else printf("Yes\n");
}
return ;
}
一血的诱惑
1001 当时鲲鲲已经做出来了,可惜卡常数,最后重现才补出来。https://blog.csdn.net/mmk27_word/article/details/101638730
1011 +1最后思路已经来了,跟题解类似,可惜没敲完。(大小姐是不写博客的)
能出的题还是挺多的,下次把所有可惜没做到的,转换成做到的。
2019CCPC秦皇岛自我反省&部分题解的更多相关文章
- 2019-ccpc秦皇岛现场赛
https://www.cnblogs.com/31415926535x/p/11625462.html 昨天和队友模拟了下今年秦皇岛的区域赛,,,(我全程在演 题目链接 D - Decimal 签到 ...
- 2019CCPC秦皇岛 E题 Escape(网络流)
Escape Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Su ...
- 2019CCPC秦皇岛D题 Decimal
Decimal Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total S ...
- 2019CCPC秦皇岛 F Forest Program
队友过的:https://blog.csdn.net/liufengwei1/article/details/101632506 Forest Program Time Limit: 2000/100 ...
- 2019CCPC秦皇岛 J MUV LUV EXTRA(KMP)
MUV LUV EXTRA Time Limit: 2000/1500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)T ...
- 2019CCPC秦皇岛 K MUV LUV UNLIMITED(博弈)
MUV LUV UNLIMITED Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- js 记录几个因惯性思维引发的代码BUG,开发思维方式的自我反省
壹 ❀ 引 在写这篇文章之前,对于取什么标题其实让我纠结了好几天,这篇文章中我想说的东西与引用类型数据有关,也与我们的惯性思维有关.本文中展示的几段代码都非常简单,原型都来自于我的日常开发,但让你立 ...
- 2019CCPC 秦皇岛 E.Escape
传送门 题意: 给出一个\(n*m\)的迷宫,有\(a\)个入口,\(b\)个出口. 现在有\(a\)个机器人都从入口出发,一开始方向默认为下,你可以选在在一些格子上面放置一个转向器,转向器有四种: ...
- 2019CCPC秦皇岛(重现赛)-D
链接: http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1004&cid=872 题意: 给定一个正整数 n,要求判断 1 ...
随机推荐
- 计算机基础与python安装
计算机基础 内容详细: 一.计算机基础 1. 计算机什么组成的 输入输出设备 cpu 硬盘 内存 中央处理器 处理各种数据 相当于人的大脑 内存 存储数据 硬盘 存储数据的 2. 什么是操作系统 控制 ...
- 【Trie】The XOR Largest Pair
[题目链接] https://loj.ac/problem/10050 [题意] 给出n个数,其中取出两个数来,让其异或值最大. [题解] 经典的01字典树问题. 首先需要把01字典树建出来. 然后对 ...
- 禅道工具的下载和使用(原地址:https://www.cnblogs.com/ydnice/p/5800256.html)
下载地址:http://sourceforge.net/projects/zentao/files/8.2/ZenTaoPMS.8.2.stable.exe/download 1.解压ZenTaoPM ...
- centos官网上对应的版本
7.4版本的链接,版本可以返回前级目录跟换,下面是各个版本的区别: 1.CentOS-7-DVD版本:DVD是标准安装盘,一般下载这个就可以了. 2.CentOS-7-NetInstall版本:网络安 ...
- [JZOJ100026]图--倍增
[JZOJ100026]图--倍增 题目链接 太懒了,自行搜索 分析 裸倍增,不多说 \(fa[i][j]\)表示\(i\)跳\(2^j\)步走到的点 \(f[i][j]\)表示\(i\)跳\(2^j ...
- ES6入门六:class的基本语法、继承、私有与静态属性、修饰器
基本语法 继承 私有属性与方法.静态属性与方法 修饰器(Decorator) 一.基本语法 class Grammar{ constructor(name,age){ //定义对象自身的方法和属性 t ...
- 连接Linux远程桌面的几个方法
有下面五种方法: 一.通过xshell或putty直接调用程序窗口(通过ssh命令行连接). 二.通过xbrower连接Linux完整的桌面. 通过xshell直接调用程序窗口. rhel5的gdm的 ...
- 使用jMeter构造大量并发的随机HTTP请求
在前一篇文章使用jMeter构造大量并发HTTP请求进行微服务性能测试里,我介绍了如何用jMeter构造并发HTTP请求.但是通过文中介绍的方式构造的并发请求,其请求参数都是硬编码的'Wang'. 有 ...
- 20.SSM整合-全注解开发
全注解开发 1.将SpringMVC改为注解 修改spring-mvc.xml 2.将Spring改为注解 将Service改为注解,完成Dao的注入 将事务以注解方式织入到Service 1.修改s ...
- mac上配置apidoc环境
1. 安装node.js 和npm 前往 https://nodejs.org/en/ 下载node.js的最新版本,双击.pkg进行安装 在终端输入 node -v ,如正确输出版本号即安装成功 ( ...