Codeforces 845 简要题解
A题
传送门
题意:2n2n2n个人下棋,分为两个阵营,每个阵营nnn个人,每个人有一个积分,积分高的能赢积分低的,问如果你可以随意选人,然后每场比赛随机安排对局,最后AAA阵的棋手能否全胜。
思路:
看积分第nnn大的和积分第n+1n+1n+1大的这两个人的积分是否相同
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int N=205;
int n,a[N];
int main(){
n=read();
for(ri i=1;i<=n*2;++i)a[i]=read();
sort(a+1,a+2*n+1);
puts(a[n]^a[n+1]?"YES":"NO");
return 0;
}
B题
传送门
题意:给你长度为666的数字串,问你最少改几个位置可以让前三个位置的数字和等于后三个位置的数字和。
思路:按照题意模拟。
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int N=205;
int n,a[N];
int main(){
char s[10];
scanf("%s",s);
int cnt=0;
for(ri i=0;i<6;++i)cnt+=i<3?s[i]-48:48-s[i];
priority_queue<int>q;
int ans=0;
if(cnt>0){
for(ri i=3;i<6;++i)q.push(9-(s[i]-48));
for(ri i=0;i<3;++i)q.push((s[i]-48)-0);
while(cnt&&cnt>=q.top())cnt-=q.top(),++ans;
if(cnt)++ans;
}
else if(cnt<0){
cnt=-cnt;
for(ri i=0;i<3;++i)q.push(9-(s[i]-48));
for(ri i=3;i<6;++i)q.push((s[i]-48)-0);
while(cnt&&cnt>=q.top())cnt-=q.top(),++ans,q.pop();
if(cnt)++ans;
}
cout<<ans;
return 0;
}
C题
传送门
题意简述:
你有两台电视,现在有很多节目,相互之间不能交叉播放,问你能否通过合理安排使得放完所有节目且每台电视上的节目都不相交。
思路:按照题意模拟。.
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int N=2e5+5;
int n,rr[2];
struct Node{
int l,r;
friend inline bool operator<(const Node&a,const Node&b){return a.l==b.l?a.r<b.r:a.l<b.l;}
}a[N];
int main(){
n=read();
for(ri i=1;i<=n;++i)a[i].l=read(),a[i].r=read();
sort(a+1,a+n+1);
rr[0]=rr[1]=-1;
for(ri i=1;i<=n;++i){
if(rr[0]>rr[1])swap(rr[0],rr[1]);
if(a[i].l<=rr[0])return puts("NO"),0;
rr[0]=a[i].r;
}
puts("YES");
return 0;
}
D题
传送门
大模拟,自己看题吧。
思路:按照题意模拟,用一个栈维护值。
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
const int N=2e5+5;
int n,ans=0,stk[N],top=0;
int main(){
n=read();
int ban1=0x3f3f3f3f,ban2=0,now=0,pre=0;
for(ri op,i=1;i<=n;++i){
op=read();
switch(op){
case 1:{
now=read();
while(top&&now>stk[top])++ans,--top;
break;
}
case 2:{
if(ban2)ans+=pre,pre=0;
break;
}
case 3:{
ban1=read(),stk[++top]=ban1;
if(now>ban1)++ans,--top;
break;
}
case 4:{
ban2=0,pre=0;
break;
}
case 5:{
ban1=0x3f3f3f3f,top=0;
break;
}
case 6:{
ban2=1,++pre;
break;
}
}
}
cout<<ans;
return 0;
}
E题
传送门
题意:给你一个n∗mn*mn∗m的矩阵,现在kkk处地方起火,每秒会使周围八个方向的格子都起火,问如果让你再任意规定一个地方起火,使得整个矩阵都起火的最小时间是多少。
思路:
考虑二分答案ttt,然后先跑一遍扫描线求出没有起火的最小横坐标x0x_0x0和没有起火的最小纵坐标y0y_0y0,这样我们可以令(x0+t,y0+t)(x_0+t,y_0+t)(x0+t,y0+t)强制起火然后再用扫描线看合不合法,扫描线的话感觉线段树写起来挺不错的 ac 了之后发现大家都什么差分之类的写的???时间在流逝啊
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=((ib=buf)+fread(buf,1,rlen,stdin)));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
typedef pair<int,int> pii;
const int N=2005;
int n,m,k;
struct pot{int x,y;friend inline bool operator==(const pot&a,const pot&b){return a.x==b.x&&a.y==b.y;}}a[N];
struct L1{int x1,x2,type;};
struct L2{int y1,y2,type;};
vector<L1>l1[N];
vector<L2>l2[N];
namespace sgt{
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
struct Node{int l,r,cnt,sum;}T[N<<2];
inline void pushup(int p){T[p].sum=T[p].cnt?T[p].r-T[p].l+1:T[lc].sum+T[rc].sum;}
inline void build(int p,int l,int r){
T[p].cnt=T[p].sum=0,T[p].l=l,T[p].r=r;
if(l==r)return;
build(lc,l,mid),build(rc,mid+1,r);
}
inline void update(int p,int l,int r,int ql,int qr,int v){
if(ql<=l&&r<=qr)return T[p].cnt+=v,pushup(p);
if(qr<=mid)update(lc,l,mid,ql,qr,v);
else if(ql>mid)update(rc,mid+1,r,ql,qr,v);
else update(lc,l,mid,ql,qr,v),update(rc,mid+1,r,ql,qr,v);
pushup(p);
}
#undef lc
#undef rc
#undef mid
}
inline pot solve(int t){
static int vx[N],sx,vy[N],sy,rx,ry;
sx=sy=0,rx=ry=-1;
for(ri i=1,x1,x2,y1,y2;i<=k;++i){
x1=max(1,a[i].x-t),y1=max(1,a[i].y-t),x2=min(n,a[i].x+t),y2=min(m,a[i].y+t);
vx[++sx]=x1,vx[++sx]=x2,vx[++sx]=x2+1;
vy[++sy]=y1,vy[++sy]=y2,vy[++sy]=y2+1;
}
vx[++sx]=1,vx[++sx]=n,vx[++sx]=n+1;
vy[++sy]=1,vy[++sy]=m,vy[++sy]=m+1;
sort(vx+1,vx+sx+1),sx=unique(vx+1,vx+sx+1)-vx-1;
sort(vy+1,vy+sy+1),sy=unique(vy+1,vy+sy+1)-vy-1;
for(ri i=1,x1,x2,y1,y2;i<=k;++i){
x1=lower_bound(vx+1,vx+sx+1,max(1,a[i].x-t))-vx;
x2=lower_bound(vx+1,vx+sx+1,min(n,a[i].x+t)+1)-vx;
y1=lower_bound(vy+1,vy+sy+1,max(1,a[i].y-t))-vy;
y2=lower_bound(vy+1,vy+sy+1,min(m,a[i].y+t)+1)-vy;
l1[y1].push_back((L1){x1,x2-1,1});
l1[y2].push_back((L1){x1,x2-1,-1});
l2[x1].push_back((L2){y1,y2-1,1});
l2[x2].push_back((L2){y1,y2-1,-1});
}
--sx,--sy;
sgt::build(1,1,sx);
for(ri i=1;i<=sy;++i){
for(ri j=0;j<l1[i].size();++j)sgt::update(1,1,sx,l1[i][j].x1,l1[i][j].x2,l1[i][j].type);
if(sgt::T[1].sum^sx){ry=vy[i];break;}
}
sgt::build(1,1,sy);
for(ri i=1;i<=sx;++i){
for(ri j=0;j<l2[i].size();++j)sgt::update(1,1,sy,l2[i][j].y1,l2[i][j].y2,l2[i][j].type);
if(sgt::T[1].sum^sy){rx=vx[i];break;}
}
for(ri i=1;i<=sy+1;++i)l1[i].clear();
for(ri i=1;i<=sx+1;++i)l2[i].clear();
return (pot){rx,ry};
}
inline bool check(const int&t){
pot tmp=solve(t);
if(tmp==(pot){-1,-1})return 1;
tmp.x+=t,tmp.y+=t;
a[++k]=tmp,tmp=solve(t),--k;
return tmp==(pot){-1,-1};
}
int main(){
n=read(),m=read(),k=read();
for(ri i=1;i<=k;++i)a[i].x=read(),a[i].y=read();
int l=0,r=1e9,ans=1e9;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid))r=mid-1,ans=mid;
else l=mid+1;
}
cout<<ans;
return 0;
}
F题
传送门
题意:给你一个n∗mn*mn∗m的格子阵nm≤250nm\le250nm≤250,每个格子是空地或者障碍,在一个空地(x,y)(x,y)(x,y)放一个守卫可以看到所有坐标为x0≥x&&y0==yx_0\ge x\&\&y_0==yx0≥x&&y0==y或者y0≥y&&x0==xy_0\ge y\&\&x_0==xy0≥y&&x0==x并且没有被障碍挡住的空地(x0,y0)(x_0,y_0)(x0,y0),问所有方法中使得至多只有一块空地没有被看到的方案数。
思路:发现nm≤250nm\le250nm≤250那么n,mn,mn,m中有一个很小,那么可以用状压dpdpdp搞过去,设fi,j,0/1,0/1f_{i,j,0/1,0/1}fi,j,0/1,0/1表示当前位置为iii,当前mmm列是否能看到的状态为jjj,当前行能否被看到,是否已经有一块空地。
然后分类讨论转移一下就完了。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
const int mod=1e9+7,N=255,M=1<<15|5;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void update(int&a,const int&b){a=add(a,b);}
char mp[N][N],s[N];
int n,m,f[2][M][2][2],ans=0,tmp=0;
int main(){
scanf("%d%d",&n,&m);
if(n<m){
for(ri i=0;i<n;++i){
scanf("%s",s);
for(ri j=0;j<m;++j)mp[j][i]=s[j];
}
swap(n,m);
}
else for(ri i=0;i<n;++i)scanf("%s",mp[i]);
f[tmp][0][0][0]=1;
for(ri up=1<<m,tt=0;tt<n;++tt){
for(ri i=0;i<m;++i){
for(ri sta=0;sta<up;++sta)for(ri s=0;s<2;++s)for(ri t=0;t<2;++t)f[tmp^1][sta][s][t]=0;
for(ri sta=0;sta<up;++sta)for(ri s=0,ns;s<2;++s)for(ri t=0;t<2;++t){
if(!f[tmp][sta][s][t])continue;
if(mp[tt][i]=='x')update(f[tmp^1][(sta|(1<<i))^(1<<i)][0][t],f[tmp][sta][s][t]);
else{
ns=i?s:0;
if(ns||((sta>>i)&1))update(f[tmp^1][sta][ns][t],f[tmp][sta][s][t]);
else if(!t)update(f[tmp^1][sta][ns][1],f[tmp][sta][s][t]);
update(f[tmp^1][sta|(1<<i)][1][t],f[tmp][sta][s][t]);
}
}
tmp^=1;
}
}
for(ri up=1<<m,sta=0;sta<up;++sta)for(ri s=0;s<2;++s)for(ri t=0;t<2;++t)update(ans,f[tmp][sta][s][t]);
cout<<ans;
return 0;
}
G题
传送门
题意:给你一个nnn个点mmm条边的带边权无向图(可能有重边自环),问从111到nnn的异或路径和最小值。
思路:考虑到最优的方案一定是一条路径的值和几个环的值异或起来,但显然不能求出所有环,仔细思考发现可以dfsdfsdfs出一棵生成树然后用线性基维护一下环的所有异或和。
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
typedef pair<int,int> pii;
const int N=1e5+5;
vector<pii>e[N];
int n,m,dis[N];
bool vis[N];
namespace xxj{
int a[31];
inline void insert(int x){if(!x)return;for(ri i=30;~i;--i)if((x>>i)&1)if(!a[i]){a[i]=x;break;}else x^=a[i];}
inline int query(int x){for(ri i=30;~i;--i)x=min(x,x^a[i]);return x;}
}
void dfs(int p,int fa){
vis[p]=1;
for(ri i=0,v;i<e[p].size();++i){
if((v=e[p][i].fi)==fa)continue;
if(!vis[v])dis[v]=dis[p]^e[p][i].se,dfs(v,p);
else xxj::insert(dis[v]^dis[p]^e[p][i].se);
}
}
int main(){
n=read(),m=read();
for(ri i=1,u,v,w;i<=m;++i)u=read(),v=read(),w=read(),e[u].push_back(pii(v,w)),e[v].push_back(pii(u,w));
dfs(1,0),cout<<xxj::query(dis[n]);
return 0;
}
Codeforces 845 简要题解的更多相关文章
- Codeforces 863 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 简要题解?因为最后一题太毒不想写了所以其实是部分题解... A题 传送门 题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数 ...
- Codeforces 381 简要题解
做的太糟糕了...第一题看成两人都取最优策略,写了个n^2的dp,还好pre-test良心(感觉TC和CF的pretest还是很靠谱的),让我反复过不去,仔细看题原来是取两边最大的啊!!!前30分钟就 ...
- Codeforces 1120 简要题解
文章目录 A题 B题 C题 D题 E题 F题 传送门 A题 传送门 题意简述:给你一个mmm个数的数列,现在规定把一个数列的1,2,...,k1,2,...,k1,2,...,k分成第一组,把k+1, ...
- Codeforces 1098 简要题解
文章目录 前言 A题 B题 C题 D题 E题 传送门 前言 没错因为蒟蒻太菜了这场的最后一道题也咕掉了,只有AAA至EEE的题解233 A题 传送门 题意简述:给出一棵带点权的树,根节点深度为111, ...
- Codeforces 1110 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 众所周知ldxoildxoildxoi这种菜鸡选手是不会写HHH题的,因此该篇博客只有AAA题至GGG题的题解,实在抱歉. A题 传送门 题 ...
- Codeforces 380 简要题解
ABC见上一篇. 感觉这场比赛很有数学气息. D: 显然必须要贴着之前的人坐下. 首先考虑没有限制的方案数.就是2n - 1(我们把1固定,其他的都只有两种方案,放完后长度为n) 我们发现对于一个限制 ...
- Codeforces 1065 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 GGG题略难,膜了一波zhouyuyang{\color{red} zhouyuyang}zhouyuyang巨佬的代码. 其余都挺清真的. ...
- Codeforces 888 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 A题 传送门 题意简述:给一个数列,问有多少个峰值点(同时比两边都大/小的点) 思路:按照题意模拟. 代码: #include<bit ...
- Codeforces 884 简要题解
文章目录 A题 B题 C题 D题 E题 F题 传送门 A题 传送门 题意简述: 一个人要完成一件事总共需要ttt秒,现在有nnn天,每天有aia_iai不能做事,问他可以在第几天做完. 思路:按照题 ...
随机推荐
- jquery中的 jquery.contains(a,b)
jquery.contains(a,b) 判断元素 a中是否包含 b 元素: 源码: contains = isNative(docElem.contains) || docElem.compareD ...
- python学习Day8 三种字符类型、文件操作
复习 类型转换 1.数字类型:int() | bool() | float() 2.str与int:int('10') | int('-10') | int('0') | float('-.5') | ...
- vue mock
如果后端不肯来帮你 mock 数据的话,前端自己来 mock 也是很简单的.你可以使用mock server 或者使用 mockjs + rap 也是很方便的. 不久前出的 easy-mock也相当的 ...
- OpenStack 安装:neutron服务
在上一篇中介绍了Nova的安装配置,这一篇介绍neutron 首先,创建neutron用户并设置密码为neutron [root@linux-node1 ~]# openstack user crea ...
- ucore-lab1-练习6report
练习6--完善中断初始化和处理 1. 中断向量表中一个表项占多少个字节?其中哪几位代表中断处理代码的入口? 答:系统将所有的中断事件统一进行编号(0-255),这个编号称为中断向量.中断向量表的一个 ...
- pandas和re中正则表达式的意思
这里()有两种意思,第一个就是表示匹配范围,另外一个就是输出这个匹配 下面那条语句就是告诉程序,是输出整个句子,“?:”非获取匹配,匹配冒号后的内容但不获取匹配结果,不进行存储供以后使用.
- Vue随笔记录
一.创建Vue步骤(VS Code) 1.全局安装 npm install -g vue-cli 2.新建项目 vue init webpack "project-n ...
- Opencv-Python学习笔记(二)
2. 使用OpenCV3处理图像 2.1 不同色彩空间的转换 OpenCV中有数百种关于在不同色彩空间之间转换的方法. 三种常用色彩空间:灰度.BGR.HSV(Hue色调,Saturation饱和度, ...
- 杭电oj 4004---The Frog Games java解法
import java.util.Arrays; import java.util.Scanner; //杭电oj 4004 //解题思路:利用二分法查找,即先选取跳跃距离的区间,从最大到最小, // ...
- 转:TCP/IP协议(一)网络基础知识
转载:http://www.cnblogs.com/imyalost/p/6086808.html 参考书籍为<图解tcp/ip>-第五版.这篇随笔,主要内容还是TCP/IP所必备的基础知 ...