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 ...
随机推荐
- 关于greenlet的一些问题
今天测试关于协程方面的代码发现我安装了greenlet模块缺导入不进.如图: 后来找了半天才发现原来greenlet被整进了gevent包中,如下导入就可以成功: 但这个greenlet没有了swit ...
- java包装类的缓存机制(转)
出处: java包装类的缓存机制 java 包装类的缓存机制,是在Java 5中引入的一个有助于节省内存.提高性能的功能,只有在自动装箱时有效 Integer包装类 举个栗子: Integer a = ...
- S02_CH02_MIO实验Enter a post title
S02_CH02_MIO实验 2.1 GPIO简介 Zynq7000系列芯片有54个MIO(multiuse I/O),它们分配在 GPIO 的Bank0 和Bank1隶属于PS部分,这些IO与PS直 ...
- Jmeter4.0---- jmeter中写入java代码_简单了解(15)
1.说明 BeanShell:是一个小型嵌入式Java源代码解释器,具有对象脚本语言特性,能够动态地执行标准JAVA语法,并利用在JavaScript和Perl中常见的的松散类型.命令.闭包等通用脚本 ...
- ECMAScript中的原型继承
//ECMAScript中的原型继承//ECMAScript中的继承主要是依靠原型链实现的.(关于原型链的介绍,详见<高三>6.3.1章节 P162) //本文示例主要为了说明SubTyp ...
- Django中 auto_now_add 和 auto_now 的区别
auto_now_add = True #创建时添加的时间 修改数据时,不会发生改变 auto_now = True #修改数据的时间,每次修改都会有变动 ........
- Qt的多线程总结以及使用(一)
Qt提供QThread类以进行多任务的处理.Qt提供的线程可以做到单个进程做不到的事情.在这里实现最简单的一个多线程.最简单的线程的基类为QThread,然后需要重写QThread的run(),在ru ...
- Javascript简单教程汇总
什么是函数 一段定义好的代码,并可以反复使用的代码块 函数的作用 提升代码的可复用性,将一段代码进行预定义,需要使用的时候才触发 代码块 形成了一个相对独立的作用域 语法: function 函数名 ...
- ASE19团队项目alpha阶段model组 scrum4 记录
本次会议于11月6日,19时整在微软北京西二号楼sky garden召开,持续50分钟. 与会人员:Jiyan He, Kun Yan, Lei Chai, Linfeng Qi, Xueqing W ...
- Delphi 10.3.3最新消息
有朋友说,已经开始内测,预计10月末发版,按最新的路线图,此版本支持iOS 13及Android 64位. 2019-11-18,今天,下载及注册机都来了,快下载安装,试用吧. 需要的话加入QQ群20 ...