AGC016题解
呼我竟然真的去刷了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题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
随机推荐
- CF1073G Yet Another LCP Problem 后缀自动机 + 虚树 + 树形DP
题目描述 记 $lcp(i,j)$ 表示 $i$ 表示 $i$ 这个后缀和 $j$ 这个后缀的最长公共后缀长度给定一个字符串,每次询问的时候给出两个正整数集合 $A$ 和 $B$,求$\sum_{i\ ...
- Appium解决native+webview混合型APP(公众号、小程序)切换webview后元素无法定位问题
问题:最近在做一个安卓+H5混合开发的APP自动化测试,发现在从native切换到webview后,元素仍然无法找到,报错:no such element 思路:于是思考webview会不会像web页 ...
- NOIp 数学知识点总结
推荐阅读 NOIp 基础数论知识点总结: https://www.cnblogs.com/greyqz/p/number.html 排列组合 常用公式 排列:\[\displaystyle A_n^m ...
- [CSP-S模拟测试]:巨神兵(状压DP)
题目描述 欧贝利斯克的巨神兵很喜欢有向图,有一天他找到了一张$n$个点$m$条边的有向图.欧贝利斯克认为一个没有环的有向图是优美的,请问这张图有多少个子图(即选定一个边集)是优美的?答案对$1,000 ...
- R python在无图形用户界面时保存图片
在用python的matplotlib,和R中自带的作图,如果想保存图片时,当你有图形用户界面时是没有问题的,但是当没有图形用户界面时,会报错: 在R中,解决办法: https://blog.csdn ...
- java后端发送请求并获取响应
URL wsUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) wsUrl.openConnection(); conn. ...
- 云计算openstack核心组件——keystone身份认证服务
一.Keystone介绍: keystone 是OpenStack的组件之一,用于为OpenStack家族中的其它组件成员提供统一的认证服务,包括身份验证.令牌的发放和校验.服务列表.用户 ...
- mariadb(二)增删改
一.表的结构的增删改 添加数据类型 alter table 表名 add 字段 数据类型: #如果字段存在则会报错 Duplicate column name '字段' #修改数据类型 alter t ...
- JavaScript 表单验证正则表达式大全
JavaScript 表单验证正则表达式大全[转载] 匹配中文字符的正则表达式: [u4e00-u9fa5] 评注:匹配中文还真是个头疼的事,有了这个表达式就好办了 匹配双字节字符(包括汉字在内):[ ...
- (appium+python)UI自动化_08_unittest编写测试用例
前言 unittest是python自带的单元测试框架,类似于Junit(Java单元测试框架).支持自动化测试,可编写测试前置&后置条件,并且可批量运行测试用例并生成测试报告. 使用unit ...