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 ...
随机推荐
- CentOS7 PHP cURL errno 35, 原因:CentOS7中没有安装curl和OpenSSL的最新版
安装OpenSSL的最新版 话不多说,直接上安装步骤 #cd /usr/local/src # 跳过证书获取失败 # wget https://www.openssl.org/source/opens ...
- golang数据基本数据类型和string类型的转换
基本类型之间的转换 golang在不同类型的变量之间赋值时需要显式转换,也就是说golang中数据类型不能自动转换. 表达式T(v)将值v转换为类型T 1.数据类型的转换可以是从范围小——>范围 ...
- 排序之快排(JS)
快速排序(Quicksort)是对冒泡排序的一种改进. 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分 ...
- hexo发布后样式丢失
修改配置中url路径,和root,问题解决.
- 关于微信小程序中的样式使用变量值的方法
在开发过程中,通常碰到样式非固定的情况,这时候就要使用变量来规定样式,例如,一个view的宽度需要使用变量: 1. 在wxss中,定义变量:width:var(--width--); 2. 在js中, ...
- js中的函数提升和变量提升
变量提升和函数提升: 就是将变量声明或者函数全部代码提升到当前作用域(全局作用域或函数作用域)最开始的部分. JavaScript中函数域为最小域范围:for循环.while循环.if语句.switc ...
- 【Git】二、文件的提交与查看
提要 //添加git跟踪文件,stage操作 $git add readme.txt //提交到本地分支 $git commit -m xxx //查看当前git工作状态,可以看到未跟踪文件,已跟踪未 ...
- Java中的集合(上):概述、Collection集合、List集合及其子类
一.集合的体系结构 二.Collection集合 1.基本使用 如下代码 import java.util.ArrayList; import java.util.Collection; public ...
- 计算机基础与python入门
一.计算机.cpu与存储器 二.操作系统.编程语言及编写python.变量 三.数据类型.输入输出及基本运算 四.流程控制之if判断.while与for循环 一.计算机.cpu与存储器 1. 什么是编 ...
- Ubuntu系统---WeChat安装
Ubuntu安装微信教程 工具/原料 ubuntu 14.04 x86 方法/步骤 这次我用的系统是Ubuntu 14.04 x86,在网上先去下载electronic-wechat-linux ht ...