呼我竟然真的去刷了016QwQ【本来以为就是个flag的233】

感觉AGC题目写起来都不是很麻烦但是确实动脑子qvq【比较适合训练我这种没脑子选手】

先扔个传送门:点我

A.Shrinking

题意:给一个串S,每一轮操作可以使S变成S'。S'[i]=S[i] 或者 S[i+1](你来选择)。每次字符串长度-1(去掉最后一个字符)。问最少几轮操作后可以使S中的字符都相同。(|S|<=100)

撕烤过程:诶?区间DP??这没法转移啊??哦凑|S|怎么这么小??暴搜就行了啊。

题解:枚举最后S中剩下的字符是什么,暴搜每次把跟这个字符相邻的字符变成它。时间复杂度O(|S|*26)

(诶等等这有点丑陋...我们是不是直接对于每种字符挂个链表,然后两个相邻的处理数是距离/2然后特殊处理一下第一个最后一个然后取max,最后对于所有取min就可以了貌似QAQ这个时间复杂度O(26+|S|)QAQ)

丑陋的暴搜代码

#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
char ch[110],cur[110];
bool check(int len,char to)
{
for(int i=0;i<len;i++) if(cur[i]!=to) return false;
return true;
}
int work(int len,char to,int cnt)
{
if(check(len,to)) return cnt;
for(int i=0;i<len;i++)
{
if(cur[i]==to)
{
if(i>0) cur[i-1]=cur[i]=to;
else cur[i]=to;
}
}
return work(len-1,to,cnt+1);
}
int main()
{
int n,i,j,ans;
scanf("%s",ch);
n=strlen(ch);ans=n;
for(i=0;i<26;i++)
{
memcpy(cur,ch,sizeof(ch));
ans=min(ans,work(n,'a'+i,0));
}
printf("%d\n",ans);
return 0;
}

B.Colorful Hats

题意:有N只戴帽子的猫(喵!)每只猫会数出除了自己以外的其他猫的帽子有几种颜色并告诉你。你来判断有没有猫说谎。(N 1e5)

撕烤过程:诶这不是小学奥数做的那种每个人帽子上有个数嘛233随便搞搞就好了233

题解:首先我们设总颜色有x个,每只猫只会看不到自己,所以如果某个颜色的帽子只有1顶的话他应该看到的x-1个,否则它会看到x个。对于x还有一些限制。比如说如果x>n/2的话那么x-1的个数一定不能少于n/2。一堆特判见代码好了qvq

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std; int a[100100],n; int main()
{
int i,j,k,cnt=0;
scanf("%d",&n);
for(i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1);
if(n==3&&a[1]==1&&a[2]==2&&a[3]==2){printf("Yes\n");return 0;}
if(a[n]-a[1]>1){printf("No\n");return 0;}
if(a[n]==a[1])
{
if(a[1]>n/2&&a[1]!=n-1) printf("No\n");
else printf("Yes\n");
return 0;
}
i=cnt=1;while(i<n&&a[i+1]==a[i]) cnt++,i++;
if(a[n]<=cnt||2*(a[n]-cnt)>n-cnt) printf("No\n");
else printf("Yes\n");
return 0;
}

C.+/- Rectangle

题意:请构造一个W*H的矩阵,使得每一个w*h的矩阵的和<0且总矩阵的和>0。(W,H,w,h 500 |数|<1e9)

撕烤过程:首先w|W&&h|H肯定构造不出来。玩玩样例照着构造,我们每放一个<0的数,一定要尽量让它影响更多的小矩阵。那么就是(i*w,j*h)的位置都放-w*h然后其他地方都放1。很好,GG了。不会了QAQ。看题解QAQ。卧槽。好暴力。

题解:首先上面的思路是对的qvq。那么是哪里GG了呢。一个例子[1,4,1,3]按照我们的方法构造出来应该是[1,1,-3,1]没有满足总和>0。然后最暴力的来了!!!我们发现因为负数影响太大,所以所有数*1000扩大影响范围[1000,1000,-2001,1000]。然后然后然后它就A掉了w【*1000的原因应该是数据范围是500qvq *1000既保证超过500的影响范围又不会爆1e9qvq 好了我编不下去了 原因就是官方题解就这么给的qvq】

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int a[510][510];
int main()
{
int h,w,H,W,i,j,ans=0;
scanf("%d%d%d%d",&H,&W,&h,&w);
if(H%h==0&&W%w==0)
{
printf("No\n");
return 0;
}
for(i=h;i<=H;i+=h)
for(j=w;j<=W;j+=w)
a[i][j]=-w*h*1000+999;
for(i=1;i<=H;i++)
for(j=1;j<=W;j++)
{
if(!a[i][j]) a[i][j]=1000;
ans+=a[i][j];
}
if(ans<0)
{
printf("No\n");
return 0;
}
printf("Yes\n");
for(i=1;i<=H;i++)
{
for(j=1;j<=W;j++)
printf("%d ",a[i][j]);
printf("\n");
}
return 0;
}

D.Xor Replace

题意:我们有两个n个元素的序列A,B(n 1e5)对于A序列,我们可以每次选取一个元素让它变成A序列的异或和。问最少几步可以使A序列变成B序列。(可能无解)

撕烤过程:emm异或和不好处理,写一下式子当我们替换掉一个Ai以后诶它变成Ai啦。所以我们对于A序列的处理其实就是A序列+异或和来回倒qvq 无解就可以这么判出来了qvq 然后我们发现我们要做的其实就是将A序列划分为x个置换,要求最小化x。肯定Ai=Bi的不用动。然后剩下一些奇奇怪怪的。悲惨的是A序列中可能会有重复QAQ 然后我就开始纠结怎么搞重复的,重复的是不是可以连一条代价边然后别的数的连进来...越想越像最小费用最大流(?)啊这不正常。弃疗。看看题解qvq

题解:我们上面的分析都是对的qvq。Ai=Bi的都直接去掉就好。剩下的我们直接连无向边(Ai,Bi)。因为值相同的是等价的,然后只要联通一定是可以构成一个置换的。把S也看做一个Ai就好qvq。我们最后的答案就是Ai!=Bi的数量+联通块的个数-1 因为不同的联通块之间转移需要多花一步来把S的位置踢下来。

(你你你在想什么!!!为什么会有费用边!!!明明是值相等直接等价!!拍桌子ing

以及我这个题蠢蠢的先写了个缩点我也不知道我脑子什么时候进的水233

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#include<stack>
using namespace std; int a[100010],b[100010],n;
map<int,int> mp,mp1;
int cnt,tot,fa[200010];
int sz; int get(int x)
{
int i=x,j;
while(fa[x]!=x) x=fa[x];
while(fa[i]!=x) j=fa[i],fa[i]=x,i=j;
return x;
} void merge(int x,int y)
{
x=get(x),y=get(y);
if(x!=y) fa[x]=y;
} int main()
{
int i,j,k,x=0,ans=1;
scanf("%d",&n);
for(i=1;i<=n;i++) scanf("%d",&a[i]),x^=a[i],mp[a[i]]++;
mp[x]++;
for(i=1;i<=n;i++)
{
scanf("%d",&b[i]);
if(!mp[b[i]]) ans=0;
else mp[b[i]]--;
}
if(!ans)
{
printf("-1\n");
return 0;
}
else
{
ans=0;
for(i=1;i<=(n<<1)+1;i++) fa[i]=i;
for(i=1;i<=n;i++)
{
if(a[i]!=b[i])
{
ans++;
if(!mp1[a[i]]) mp1[a[i]]=++cnt;
if(!mp1[b[i]]) mp1[b[i]]=++cnt;
merge(mp1[a[i]],mp1[b[i]]);
}
}
if(!ans)
{
printf("0\n");
return 0;
}
if(!mp1[x]) mp1[x]=++cnt;
for(i=1;i<=cnt;i++) if(get(i)==i) ans++;
printf("%d\n",ans-1);
}
return 0;
}

E.Poor Turkeys

题意:有n(n 400)只可怜的火鸡。有M(M 1e5)个猎人,每个猎人有两个目标火鸡,如果两只火鸡都还活着那么他会随机打死一只带走,如果只有一只活着,他就直接打死这只拿走,没有活着的,就不做操作跑路。问有多少对(无序对)火鸡有机会都活下来。

撕烤过程:无。这个题是在某校讲状压dp的时候学的QwQ。后来在另外某校模拟赛考到原题也是有点巧233

题解:这个题我在思路总结里写过233

逆向思考。对于一只火鸡x有机会活下来,那么有关于他的每一轮就要活下来,也就是跟他相关的另一只y必须死。所以我们按照时间顺序倒着扫,和他相关的那只y必须在“这一轮”死,所以y一定在之前的所有轮里都要活下来,如果y重复出现,y肯定不能来会死,所以x就没有机会活下来。往前推就好了。所以会得到一个有关于x的存活集合,也就是说这个集合的火鸡一定是以一定顺序挂掉来保证x最后活下来。

对于我们统计的无序对i,j来说,首先它们一定各自有机会活下来,然后它们的存活集合一定不能有交。因为一旦有交的话那么它相对的那只火鸡就来回死了。十分暴力的一个题233。时间复杂度是O(n^3+nm)用bitset优化可以到O(n^3/w+nm)但是那样就太毒瘤啦!!

突然发现我就写的bitset。

真香。

// Love and Freedom.
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<bitset>
#define maxn 500
using namespace std; int a[110000],b[110000];
bool dead[maxn];
bitset<maxn> g[maxn]; int main()
{
int n,i,m,j,k,x,y,ans=0;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++) scanf("%d%d",&a[i],&b[i]);
for(i=1;i<=n;i++)
{
g[i][i]=1;
for(j=m;j;j--)
{
x=g[i][a[j]];y=g[i][b[j]];
if(x&&y)
{
dead[i]=1;
break;
}
else
{
if(x) g[i][b[j]]=1;
if(y) g[i][a[j]]=1;
}
}
}
for(i=1;i<n;i++)
{
if(dead[i]) continue;
for(j=i+1;j<=n;j++)
{
if(dead[j]) continue;
int cur=1;
for(k=1;k<=n;k++)
if(g[i][k]&&g[j][k])
{
cur=0;
break;
}
ans+=cur;
}
}
printf("%d\n",ans);
return 0;
}

F.Games on DAG

题意:有一个n个点m条边的DAG,在1号点和2号点上各有一枚棋子,两个人每次任选一枚棋子移动,当两枚棋子都不能动了就算失败。对于每一条边有出现不出现两种可能,问在2^m种图中,先手必胜的图有多少个。(n 15)

撕烤过程:15...貌似只能状压?做不来...弃疗...看题解...看不懂...QAQ

题解:我们先考虑一张图的是否先手必胜。SG函数直接上就好了。只要1号点和2号点SG不同即可。也就是分个层。

SG不同很明显不好算。我们就容斥一下计算SG相同的方案数。最后2^m-计算出来的结果就行了。

令f[s]表示当SG(1)=SG(2)时,考虑的点集合为s的方案数。我们枚举s的子集t,补集t'。设t'中SG都是0,t由t'转移。

因为SG(u)=SG(v|(u,v)),所以我们对t和t'有一些限制。

1.t'中的每个点至少向t中的点连1条边。(使t的SG由t'转移)

2.t向t'没有限制。

3.t'中的点互相不能有边,不然就不存在这个集合了。

转移对了以后我们剩下一个预处理。预处理每个点连向别的点集的方案数,这个看代码好了QvQ

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define mxn (1<<16)
#define ll long long
#define lowbit(x) (x&-x)
#define mdn 1000000007
using namespace std; int f[mxn],in[16],n,m;
int b[16][mxn];
int sg[16][mxn],cnt[16][mxn]; int main()
{
int i,j,x,y,k;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);x--;y--;
b[x][1<<y]=1;
}
for(i=0;i<n;i++)
for(j=1;j<(1<<n);j++)
cnt[i][j]=cnt[i][j^lowbit(j)]+b[i][lowbit(j)];
f[0]=1;
for(i=1;i<(1<<n);i++)
{
if(((i&3)==3)||((i&3)==0))
{
f[i]=1;
for(j=i;~j;j=(j?(j-1)&i:j-1))
{
if(j==i||j==0) continue;
if(((j&3)!=0)&&((j&3)!=3)) continue;
int cur=f[j^i];
for(k=0;k<n;k++)
{
if(j&(1<<k))
cur=((ll)cur*(1ll<<cnt[k][i^j])%mdn)%mdn;
else if(i&(1<<k))
cur=((ll)cur*((1ll<<cnt[k][j])-1ll)%mdn)%mdn;
}
f[i]=((ll)f[i]+cur)%mdn;
}
}
}
int cur=1;
for(i=1;i<=m;i++) cur=(cur<<1ll)%mdn;
printf("%d\n",((ll)cur-f[(1<<n)-1]+mdn)%mdn);
return 0;
}

呼。顺着写完一场AGC还是很开(du)心(liu)的qvq。

atcoder题目质量真的很高啊,好感++

下一个目标:AGC018 finish by 10.19(题解咕到周末就好233)

AGC016题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. LintCode之移动零

    题目描述: 分析:由于要使非零元素保持原数组的顺序,我只能想出在找到一个0时,逐个移动数组元素使得后一个元素覆盖前一个元素,再将这个0移到后头去. 我的代码: public class Solutio ...

  2. PHP垃圾回收深入理解

    转摘于http://www.cnblogs.com/lovehappying/p/3679356.html PHP是一门托管型语言,在PHP编程中程序员不需要手工处理内存资源的分配与释放(使用C编写P ...

  3. File upload with cropping support using Cropper --jquery file upload

    File upload with cropping support using Cropper demo https://tkvw.github.io/jQuery-File-Upload/basic ...

  4. python使用中遇到的一些问题

    一./usr/bin/ld:cannot find -lxxx错误 例如出现了问题: /usr/bin/ld:cannot find -lssl 其中xxx表示函式库文件名称,如上面的libssl.s ...

  5. Docker容器内部端口映射到外部宿主机端口

    Docker允许通过外部访问容器或者容器之间互联的方式来提供网络服务.容器启动之后,容器中可以运行一些网络应用,通过-p或-P参数来指定端口映射. 注意:宿主机的一个端口只能映射到容器内部的某一个端口 ...

  6. Flask 重定向到动态url

    url_for() 函数是动态构建一个网址给特定的功能是非常有用的.该函数接受函数的名称作为第一个参数,并接受一个或多个关键字参数,每个参数对应于URL的变量部分. 以下脚本演示了使用 url_for ...

  7. StringTokenizer拆分字符串

    今天要做一个过滤特殊字符的需求, 看了下公司以前过滤特俗字符代码, 用的居然是 StringTokenizer, 完全不熟悉啊, 于是恶补了一下, 把StringTokenizer在JDK中的文档也翻 ...

  8. Grafana+Prometheus系统监控之Redis

    REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C语言编写.遵守B ...

  9. Using Tensorflow SavedModel Format to Save and Do Predictions

    We are now trying to deploy our Deep Learning model onto Google Cloud. It is required to use Google ...

  10. MySQL集群(PXC)入门

    一.学习动机 伴随互联网行业的兴起,越来越多的领域需要相应的技术方案,比如:打出软件.电商平台.直播平台.电子支付.媒体社交. 身边常见的,校园出成绩那一年,我们会感觉网站异常的卡顿,因为访问人数太多 ...