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不能做事,问他可以在第几天做完. 思路:按照题 ...
随机推荐
- js生成二维码并保存成图片下载
我这里使用是jQuery,和jquery.qrcode.js,需要的可以自己找链接下载.示例代码仅做参考 html代码: <a id="downloadLink">&l ...
- 2017-11-11 Sa Oct Is it online
2017-11-11 Sa Oct Is it online 9:07 AM After breakfast I tried connecting to the course selection sy ...
- 20175213 2018-2019-2 《Java程序设计》第8周学习总结
教材学习内容总结 1:泛型主要目的是建立具有类型安全的集合框架,如链表,散列映射等数据结构. 泛型类的声明: class People<E> People是泛型类的名称,E是其中泛型,E可 ...
- 关于SQL 导出脚本失败 及SQL 的重装
说点题外话 最近跳到一家新公司 薪资比较客观 但是技术可能不太尽如人意 而且对.Net方向的开发好像不是很友好 自己也不知道该怎么办 一个人大老远跑这边来 附近也没有什么.net的公司和职位 房子租 ...
- try-catch-finally 与返回值的修改
先看一段java代码,func返回值为int: public static int func() { int result = 0; try { result = 1; return result; ...
- step_by_step_ABP规约模式
一段时间没有在github 上浏览ABP项目,几天前看到ABP新增规约模式,开始了解并学习文档 记录一下 Introduction 介绍 Specification pattern is a pa ...
- 获取select下拉框选中的的值
有一id=test的下拉框,怎么获取选中的那个值呢? 分别使用javascript方法和jquery方法 <select id="test" name="&quo ...
- 简单的页面互点Javascript代码
简单的页面互点Javascript代码,可以适用于前端$(function(){ $('.ip_b_con_item li,.pro_index_list li').mouseover(functio ...
- Android 代码判断是否有网络
public void okGo() { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemServic ...
- Redux 检测状态树变更
一 概述 Redux只是检测引用是否改变. 如果状态树的某个值是对象.数组等,在reducer中需要生成一个新对象.新数组,才能被Redux检测到变更. let fruits = ['apple',' ...