$ Solution \ on \ CF1562A $
第一眼看到这个题的时候没啥思路,然后一瞅到最后一个样例就猜出来了结论
显然可以发现,设答案为 $ f(l,r) $ ,对于 $ f(1,r) $ ,都有 $ f(1,r)= r % ( \lfloor \frac{r}{2} \rfloor +1 ) $ ,因为 $ r ; $ 模任意一个比 $ \lfloor \frac{r}{2} \rfloor $ 小的数字 $ x $ 的答案都小于 $ r ; % ; 2x $,而 $ r ; % ; 2x < r ; % ; ( \lfloor \frac{r}{2} \rfloor +1 ) $
考虑左端点不是 $ 1 $ 的情况,发现 $ b $ 越小答案越大( $ a肯定选择r$ ),所以最后的答案就是 $ r ; % ; \max { l,\lfloor \frac{r}{2} \rfloor +1 } $
int main(){
read(T);
while(T--){
read(l),read(r);
outn(r%std::max(l,(r/2+1)));
}
return 0;
}
$ Solution \ on \ CF1562B $
可以发现,答案的位数最大是 $ 2 . $ 因为如果给定的串中的某一位是合数,直接输出这个数字就好了;如果除了第一位,后面某一位出现了数字 $ 5 $ 或者数字 $ 2 $ ,则答案一定是两位的(前面选一个数字,作为十位,这个位置的数字作为个位,一定是合数);如果出现了相同的两个数字,答案也一定是两位的(这两个相同的数字肯定能组成 $ 11 $ 的倍数);那么剩下的情况中,除了第一位,后面的每一位都只能是 $ 3 $ 或者 $ 7 $ 且这两个数字只能出现一次(发现这样满足的算第一个位置的最大长度为 $ 3 $),否则都会被前面的几条判定出来,考虑第一位是什么,因为题目保证了会有合法情况,所以第一位一定能和后面两位中的一位形成一个合数,所以这种情况的答案的最大位数也是 $ 2 .$
注意题目说明,有 $ 1 $ 直接输出 $ 1 $ 即可
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define $int long long
/***************快读***************/
namespace IO {
char buf[1<<21], *p1 = buf, *p2 = buf, buf1[1<<21];
inline char gc () {return p1 == p2 && (p2 = (p1 = buf) + fread (buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;}
#ifndef ONLINE_JUDGE
#endif
#define gc getchar
template<class I>
inline void read(I &x) {
x = 0; I f = 1; char c = gc();
while(c < ‘0‘ || c > ‘9‘) {if(c == ‘-‘) f = -1; c = gc(); }
while(c >= ‘0‘ && c <= ‘9‘) {x = x * 10 + c - ‘0‘; c = gc(); }
x *= f;
}
template<class I>
inline void write(I x) {
if(x == 0) {putchar(‘0‘); return;}
I tmp = x > 0 ? x : -x;
if(x < 0) putchar(‘-‘);
int cnt = 0;
while(tmp > 0) {
buf1[cnt++] = tmp % 10 + ‘0‘;
tmp /= 10;
}
while(cnt > 0) putchar(buf1[--cnt]);
}
#define in(x) read(x)
#define outn(x) write(x), putchar(‘\n‘)
#define out(x) write(x), putchar(‘ ‘)
} using namespace IO;
/***************快读***************/
#define maxn 1000010
int T,n;
int a[maxn];
bool vis[maxn];
int dabiao[]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
char s[maxn];
int main(){
read(T);
for(int i=1;i<=25;i++){vis[dabiao[i]]=1;}
while(T--){
// puts("");
bool flag=false;
read(n);
::cin>>(s+1);
for(int i=1;i<=n;i++){a[i]=s[i]-‘0‘;}
for(int i=1;i<=n&&flag==false;i++){if((a[i]%2==0&&a[i]!=2)||a[i]==9||a[i]==1){outn(1);outn(a[i]);flag=true;}}
for(int i=1;i<=n&&flag==false;i++){
for(int j=i+1;j<=n&&flag==false;j++){
if(!vis[a[i]*10+a[j]]){
outn(2);
outn(a[i]*10+a[j]);
flag=true;
}
}
}
// puts("");
}
return 0;
}
$ Solution \ on \ CF1562C $
诈骗题,千万不要想多了。
注意到任何一个数字的二进制左边或者右边填 $ 0 $ 之后的结果都是原数字的倍数,例如
$ { (10010)2 * (2){10} = (100100)_2 } $
$ { (10010)_2 = (1001)2 * (2){10} } $
(设第一个串为 $ t $ , 第二个串为 $ m $)
于是找到第一个 $ 0 $ 出现的位置就可以解决这个问题了,因为如果它第一个出现的位置 $ pos_0 $ 在前一半,构造 $ t[pos:n] $ , $ m[pos+1:n] $ ; 否则构造 $ t[1:pos] $ , $ m[1:pos-1] $即可满足条件
注意如果整个数列都是 $ 1 $ ,构造 $ t $ 为整个数列, $ m $ 为任何一个长度大于等于 $ \lfloor \frac{n}{2} \rfloor $ 的连续的子串即可满足条件
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define $int long long
/***************快读***************/
namespace IO {
char buf[1<<21], *p1 = buf, *p2 = buf, buf1[1<<21];
inline char gc () {return p1 == p2 && (p2 = (p1 = buf) + fread (buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;}
#ifndef ONLINE_JUDGE
#endif
#define gc getchar
template<class I>
inline void read(I &x) {
x = 0; I f = 1; char c = gc();
while(c < ‘0‘ || c > ‘9‘) {if(c == ‘-‘) f = -1; c = gc(); }
while(c >= ‘0‘ && c <= ‘9‘) {x = x * 10 + c - ‘0‘; c = gc(); }
x *= f;
}
template<class I>
inline void write(I x) {
if(x == 0) {putchar(‘0‘); return;}
I tmp = x > 0 ? x : -x;
if(x < 0) putchar(‘-‘);
int cnt = 0;
while(tmp > 0) {
buf1[cnt++] = tmp % 10 + ‘0‘;
tmp /= 10;
}
while(cnt > 0) putchar(buf1[--cnt]);
}
#define in(x) read(x)
#define outn(x) write(x), putchar(‘\n‘)
#define out(x) write(x), putchar(‘ ‘)
} using namespace IO;
/***************快读***************/
#define maxn 1000010
int T,n;
char s[maxn];
int pos_0;
int main(){
read(T);
while(T--){
pos_0=-1;
read(n);
::cin>>(s+1);
for(int i=1;i<=n;i++){if(s[i]==‘0‘){pos_0=i;i=n+1;}}
if(pos_0==-1){
out(1),out(2*(n/2)),out(1),outn(n/2);
} else if(pos_0<=(n/2)){
out(pos_0),out(n),out(pos_0+1),outn(n);
} else{
out(1),out(pos_0),out(1),outn(pos_0-1);
}
}
return 0;
}
$ otherwise $
$ \color{purple} { 我不会惹呜呜呜 } $