Contest Link Official Editorial

A. Subtract or Divide

给你一个数 \(n\) ,每一步可以做以下两个操作之一:

  • 用一个不等于 \(n\) 的 \(n\) 的约数除 \(n\)
  • \(n-1\)

问变成 \(1\) 的最小步数。

Solution

又是赛时乱搞……赛时一开始写了一个除了质数以外能除就除的东西,然后交上去 Wa on 2 ;于是又加了一个奇数就减偶数就除的东西,两个取 \(\min\) ,就过了……(其实这个想法貌似就是正解……当时还挺担心会被 Hack )


如果 \(n\leq 3\) ,直接输出答案。

否则,如果 \(n\) 是奇数,那么 n-1 是偶数,然后可以直接变成 \(2\) ,答案是 \(3\) .

如果 \(n\) 是偶数,那就直接变 \(2\) ,答案是 \(2\) .

Code

//Author: RingweEH
int find( int x )
{
int lim=sqrt(x);
for ( int i=2; i<=lim; i++ )
if ( x%i==0 ) return x/i;
return -1;
} int main()
{
int T=read();
while ( T-- )
{
int n=read(),sav=n; int cnt=0;
while ( n!=1 )
{
cnt++; int x=find(n);
if ( x==-1 ) n--;
else n/=x;
}
int cnt2=0; n=sav;
while ( n!=1 )
{
cnt2++; int x=find(n);
if ( (n&1) || (x==-1) ) n--;
else n/=x;
}
printf( "%d\n",min(cnt,cnt2) );
}
}

B. Non-Substring Subsequence

给定一个长度为 \(n\) 的01串 \(s\) 和 \(q\) 个询问。每个询问形如 \(l_i,r_i\) 要求:

  • 求出 \(s\) 的一个 子序列 使其等于 \(s[l_i,r_i]\) 且不连续。

问是否存在这样的子序列。

Solution

其实想一下就会发现,如果找不到,那么肯定只有 \([l_i,r_i]\) 这一个连续的子序列。

如果找到了,说明至少能把 \([l_i,r_i]\) 的头往前移或者把尾往后移。(因为 \([l_i,r_i]\) 是相邻的,要是能移动肯定是满足能移动头尾的)

所以判断 \(s[1,l_i-1]\) 中是否存在 \(s[j]=s[l_i]\) 即可,\(r_i\) 同理。

Code

//Author: RingweEH
int l=read(),r=read(); bool fl=0;
for ( int i=1; i<l; i++ )
if ( s[i]==s[l] ) fl=1;
for ( int i=n; i>r; i-- )
if ( s[i]==s[r] ) fl=1;
fl ? printf( "YES\n" ) : printf( "NO\n" );

C. String Equality

给定两个由小写英文字符组成的字符串 \(a,b\) .对 \(a\) 可以进行两个操作:

  • 交换两个相邻字符
  • 把连续 \(k\) 个同样的字符变成其后继

问能否把 \(a\) 变成 \(b\) .

Solution

能交换字符说明不需要考虑顺序问题。记 \(cnta[c],cntb[c]\) 为 \(c\) 在 \(a,b\) 中出现的次数。

由题目可知,如果要改变字符只能变大不能变小。

所以正序扫一遍这两个数组,

  • 如果 \(cnta[i]\ge cntb[i]\) ,如果多出来的部分不能被 \(k\) 整除,那么显然无解,因为你不可能把这部分变掉。否则,把这一部分累加进 \(cntk\) 里面,供后面不够的时候使用。(这样保证只能从前面往后面贡献)
  • 如果 \(cnta[i]<cntb[i]\) ,如果少的部分不能整除同理。如果累计的 \(cntk\) 不够用了还是无解。否则把 \(cntk\) 减去 \((cntb[i]-cnta[i])/k\) 即可。

Code

//Author: RingweEH
n=read(); k=read(); scanf( "%s",sa ); scanf( "%s",sb );
for ( int i=0; i<n; i++ )
cnta[sa[i]-'a']++,cntb[sb[i]-'a']++;
int cntk=0; bool fl=1;
for ( int i=0; i<25; i++ )
{
if ( cnta[i]>=cntb[i] )
{
if ( ((cnta[i]-cntb[i])%k)!=0 ) { fl=0; break; }
cntk+=(cnta[i]-cntb[i])/k;
}
else
{
if ( ((cntb[i]-cnta[i])%k)!=0 ) { fl=0; break; }
int del=(cntb[i]-cnta[i])/k;
if ( del>cntk ) { fl=0; break; }
cntk-=del;
}
}
if ( fl ) printf( "Yes\n" );
else printf( "No\n" );

D. Circle Game

\(\text{Ashish}\) 先手,\(\text{Utkarsh}\) 后手。

在一个二维平面上,有一个棋子被放在 \((0,0)\) 处。每一步移动可以让 \(x\) 或者 \(y\) 坐标增加 \(k\) ,且每一步必须在以 \((0,0)\) 为圆心, \(d\) 为半径的圆内。不能移动判负。问谁必胜。

Solution

显然,一开始只要 \(Ashish\) 能动,\(Utkarsh\) 都能在另一维坐标上相应移动。最后会到达点 \((k\times z,k\times z)\) 。

这时候,如果 \((k\times z,k\times (z+1))\) 在圆内,那么先手胜;否则后手胜。

Code

//Author: RingweEH
ll d=read(),k=read(),z=1;
while ( sqr(z*k)*2<=sqr(d) ) z++; z--;
if ( sqr(z*k)+sqr(z*k+k)<=sqr(d) ) printf( "Ashish\n" );
else printf( "Utkarsh\n" );

E1+2. Bitwise Queries (Hard Version)

交互题。有三种询问形式:

  • AND i j : \(a_i \& a_j\)
  • OR i j : \(a_i|a_j\)
  • XOR i j : \(a_i\oplus a_j\)

保证 \(a_i\in[0,n-1]\) 。要求在不超过 \(n+1\) 次询问中得到整个序列。

Solution

分两种情况讨论。首先,\(n-1\) 次询问 \(a[1]\oplus a[i]\) .

  • 存在 \(a[x]=a[y]\) . 有两种可能,一种是出现 0 ,另一种是有两个结果相等。无论是哪种都可以把两个相等的数 \(\&\) 一下得到具体值,反推即可。
  • 否则,显然每个数都是唯一的。必定存在一个数 \(a[x]\oplus a[1]=1\) ,然后询问 \(a[1]\text{ and } a[x]\) ;再找一个 \(a[y]\oplus a[1]=3\) ,如果 \(a[x]\text{ and }a[y]=1\) 说明 \(1\) 在 \(a[x]\) ,否则在 \(a[y]\) ,这样就得到了 \(a[1]\) ,进而可以推知全部的数。

Code

//Author: RingweEH
int get_query( int opt,int x,int y )
{
if ( opt==1 ) cout<<"AND "<<x<<" "<<y<<endl;
else if ( opt==2 ) cout<<"OR "<<x<<" "<<y<<endl;
else if ( opt==3 ) cout<<"XOR "<<x<<" "<<y<<endl;
cout.flush(); int tmp; cin>>tmp; return tmp;
} int main()
{
cin>>n; sum[0]=1; int id=0;
for ( int i=2; i<=n; i++ )
{
int tmp=get_query( 3,1,i ); ans[i]=tmp;
if ( !sum[tmp] ) sum[tmp]=i;
else id=i;
} if ( id )
{
int tmp=get_query( 1,sum[ans[id]],id );
ans[1]=ans[id]^tmp;
for ( int i=2; i<=n; i++ )
ans[i]^=ans[1];
}
else
{
int t1=get_query(1,sum[1],1),t2=get_query(1,sum[2],1);
int tmp=t1+t2%2;
for ( int i=1; i<=n; i++ )
ans[i]^=tmp;
}
cout<<"! ";
for ( int i=1; i<=n; i++ )
cout<<ans[i]<<' ';
return 0;
}

F. Nullify The Matrix

给定一个 \(n\times m\) 的矩阵,元素为非负数。轮流操作:

  • 选一个非零点 \((r_1,c_1)\) 作为起点,一个点 \((r_2,c_2)\) 满足 \(r_2\ge r_1,c_2\ge c_1\) 作为终点。
  • 将 \(a_{r_1,c_1}\) 的值减小为 \([0,a_{r_1,c_1}-1]\) 。
  • 任选一条从开始点 \((r_1,c_1)\) 到结束点 \(r_2,c_2\) 的一条最短路,并修改路径上点为一个非负数。(最短路是单元格个数,每个单元格可以单独修改)
  • 路径上的点不包含起点但包含终点。如果起始相同那么单元格的值减小。

当矩阵的数全部为 0 时,无法操作的一方输。问胜者。

Solution

结论:

令常数 \(d\) 为斜对角线上 \(r,c\) 坐标之和,\(xor(d)=a_{r_1,c_1}\oplus a_{r_2,c_2}\oplus...\oplus a_{r_n,c_n}(r_i+c_i==d)\) 。

如果对于所有的 \(d\) ,在游戏开始时有 \(xor(d)=0\) ,那么后手胜,否则先手必胜。(深刻感受到翻译的痛苦)

Let's consider diagonals \(d\) of the form \(r+c\) - the diagonals where the sum of row index (r) and column index (c) is constant. Then xor of a diagonal \(d\) will be \(xor(d)=a(r1,c1)⊕a(r2,c2)⊕...a(rn,cn)\) , such that \(r_1+c_1=d\) , \(r_2+c_2=d\) , .... \(r_n+c_n=d\) .

If \(0∀d,xor(d)=0\) at the start of the game, then Jeel wins. Else, Ashish wins.

\(Proof\) :设状态 \(S_1\) 为对于任意的 \(d\) ,\(xor(d)=0\) ;设状态 \(S_2\) 为存在 \(d\) 使得 \(xor(d)\neq 0\) .

\(Lemma1\) :对 \(S_1\) 中状态进行的任何操作都将转移到 \(S_2\) .由于起点不能在路径中被改变且在开头必须被改成一个 \([0,a_{r_1,c_1}-1]\) 之间的数,所以异或和一定不为0.

\(Lemma2\) :永远存在一种转移使得 \(S_2\) 中的状态能转移到 \(S_1\) 中。对于一个状态,如果其异或值不为 0 ,总能选择一个数,让它变小之后异或值为 0 .


发现 \(S_1\) 属于败集。那么如果初始状态属于 \(S_2\) ,先手就总能把败局留给后手,而后手只能把胜局留给先手。

复杂度 \(\mathcal{O}(n\times m)\) .

Code

//Author: RingweEH
int main()
{
int T=read();
while ( T-- )
{
memset( sum,0,sizeof(sum) ); n=read(); m=read();
for ( int i=1; i<=n; i++ )
for ( int j=1; j<=m; j++ )
{
a[i][j]=read(); sum[i+j]^=a[i][j];
} bool fl=1;
for ( int i=1; i<=n+m; i++ )
fl&=(sum[i]==0); if ( !fl ) printf( "Ashish\n" );
else printf( "Jeel\n" );
}
}

Codeforces Round #685(Div2)的更多相关文章

  1. Codeforces Round #539 div2

    Codeforces Round #539 div2 abstract I 离散化三连 sort(pos.begin(), pos.end()); pos.erase(unique(pos.begin ...

  2. 【前行】◇第3站◇ Codeforces Round #512 Div2

    [第3站]Codeforces Round #512 Div2 第三题莫名卡半天……一堆细节没处理,改一个发现还有一个……然后就炸了,罚了一啪啦时间 Rating又掉了……但是没什么,比上一次好多了: ...

  3. Codeforces Round#320 Div2 解题报告

    Codeforces Round#320 Div2 先做个标题党,骗骗访问量,结束后再来写咯. codeforces 579A Raising Bacteria codeforces 579B Fin ...

  4. Codeforces Round #564(div2)

    Codeforces Round #564(div2) 本来以为是送分场,结果成了送命场. 菜是原罪 A SB题,上来读不懂题就交WA了一发,代码就不粘了 B 简单构造 很明显,\(n*n\)的矩阵可 ...

  5. Codeforces Round #361 div2

    ProblemA(Codeforces Round 689A): 题意: 给一个手势, 问这个手势是否是唯一. 思路: 暴力, 模拟将这个手势上下左右移动一次看是否还在键盘上即可. 代码: #incl ...

  6. Codeforces Round #626 Div2 D,E

    比赛链接: Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics) D.Present 题意: 给定大 ...

  7. CodeForces Round 192 Div2

    This is the first time I took part in Codeforces Competition.The only felt is that my IQ was contemp ...

  8. Codeforces Round #359 div2

    Problem_A(CodeForces 686A): 题意: \[ 有n个输入, +\space d_i代表冰淇淋数目增加d_i个, -\space d_i表示某个孩纸需要d_i个, 如果你现在手里 ...

  9. Codeforces Round #360 div2

    Problem_A(CodeForces 688A): 题意: 有d天, n个人.如果这n个人同时出现, 那么你就赢不了他们所有的人, 除此之外, 你可以赢他们所有到场的人. 到场人数为0也算赢. 现 ...

随机推荐

  1. 淘宝客?CPS技术是怎么实现的?

    前言 微信搜[Java3y]关注这个有梦想的男人,点赞关注是对我最大的支持! 文本已收录至我的GitHub:https://github.com/ZhongFuCheng3y/3y,有300多篇原创文 ...

  2. Socket bind系统调用简要分析

    主要查看linux kernel 源码:Socket.c 以及af_inet.c文件 1.1 bind分析 #include <sys/types.h> /* See NOTES */#i ...

  3. 僵尸进程与SIGCHLD信号

    什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打开的文件等,但内核为每一个终止子进程保存了一定量的信息.这些信息至少包括进程ID,进程的终止状态,以及该 ...

  4. hibernate 基础知识

    1.hibernate的配置文件,一般放在classpath的根目录下,默认命名为hibernate.cfg.xml,代码例子如下: <!DOCTYPE hibernate-configurat ...

  5. HTTP介绍(一)

    超文本传输协议(HTTP)是一种用于分布式,协作式超媒体信息系统的应用程序层协议.HTTP是万维网(World Wide Web)数据通信的基础,超文本文档包括指向用户可以轻松访问的其他资源的超链接, ...

  6. 面试官:小伙子,你给我说一下Java Exception 和 Error 的区别吧?

    前言 昨天在整理粉丝给我私信的时候,发现了一个挺有意思的事情.是这样的,有一个粉丝朋友私信问我Java 的 Exception 和 Error 有什么区别呢?说他在面试的时候被问到这个问题卡壳了,最后 ...

  7. 用Camtasia设计微课视频封面,让课程更加高大上

    在网络时代,尤其现在疫情影响只能线上学习,微课的应用前景已经越来越广了.但是想把微课做好,只有内容与录制精细是不够的,还需要一个精美的封面来吸引学生.接下来,小编就用微课制作软件Camtasia 20 ...

  8. zabbix 用Telegram报警!!!

    第一步:先在Telegram 注册个机器人!!! @BotFather在Telegram中添加联系人并按"开始",然后键入: /newbot输入你要新建的机器人名称在电报中@你的机 ...

  9. Linux查看并杀死被占用的端口

    sudo apt-get install lsof     //安装lsof sudo lsof -i:端口号 //查找对应的进程号 sudo kill -9 进程号 //杀死对应的进程

  10. python应用(3):启用集成开发工具pycharm

    之前写了个python程序给自己用,写代码时用的是macvim(vim的一种),macvim是个编辑工具,由于我已经设置过对python等各种语言的支持特性,所以什么缩进.对齐.高亮之类的表现都有,写 ...