Gardener and the Capybaras (easy version)
思路:
纯暴力,for
循环确定每个子串的长度,用 substr
来截取子串。
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int T;
scanf("%d", &T);
while(T--){
string s;
cin>>s;
int len = s.length();
string tmp1, tmp2, tmp3;
bool flag = false;
for(int i = 0;i < len;i++){
for(int j = 1;j < len - i - 1;j++){
tmp1 = s.substr(0, i + 1);
tmp2 = s.substr(i + 1, j);
tmp3 = s.substr(i + j + 1);
if((tmp1 <= tmp2 && tmp3 <= tmp2) || (tmp1 >= tmp2 && tmp3 >= tmp2)){
cout<<tmp1;
printf(" ");
cout<<tmp2;
printf(" ");
cout<<tmp3;
printf("\n");
flag = true;
break;
}
}
if(flag) break;
}
if(!flag) printf(":(\n");
}
return 0;
}
Gardener and the Capybaras (hard version)
思路:
-
将输入字符串掐头去尾(从第二个到倒数第二个)后,若其中第 i i i 位有
a
,则将字符串分成为(1, i - 1)(i, i)(i + 1, n)后可满足 a ≥ b , c ≥ b a \ge b,c \ge b a≥b,c≥b 的条件 -
否则,将字符串分成为(1, 1)(2, n - 1)(n, n)三段,可满足 a ≤ b , c ≤ b a \le b,c\le b a≤b,c≤b 的条件
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int T;
scanf("%d", &T);
while(T--){
string s;
cin>>s;
int len = s.length();
int index = -1;
for(int i = 1;i < len - 1;i++){
if(s[i] == 'a'){
index = i;
break;
}
}
if(index != -1){
for(int i = 0;i < index;i++){
printf("%c", s[i]);
}
printf(" %c ", s[index]);
for(int i = index + 1;i < len;i++){
printf("%c", s[i]);
}
printf("\n");
}
else{
printf("%c ", s[0]);
for(int i = 1;i < len - 1;i++){
printf("%c", s[i]);
}
printf(" %c\n", s[len - 1]);
}
}
return 0;
}
Gardener and the Array
思路:
猜想 x = a x=a x=a, y y y 为 a a a 中删除一个数字的子序列,则 $f(a) = f(b) $时,必定有其他的数也有这一位。用数组统计,遍历所有数看能否删除。
PS:多组数据注意清空
PS2:时限卡得很紧,不能用普通的初始化方法
代码:
#include<bits/stdc++.h>
using namespace std;
template<typename T> inline void read(T &x){
T a = (T)0, b = (T)1;
char ch = ' ';
while(ch != '-' && (ch < '0' || ch > '9')){
ch = getchar();
}
if(ch == '-'){
b = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
a = ((T)a << 3) + ((T)a << 1) + (ch ^ '0');
ch = getchar();
}
x = a * b;
}
template<typename T> inline void write(T x, char c = '\0') {
if(x < (T)0){
putchar('-');
x = -x;
}
if(x > (T)9){
write(x / (T)10);
}
putchar(x % (T)10 + '0');
if(c != '\0'){
putchar(c);
}
}
const long long NR = 1e5;
const long long MR = 2 * 1e5;
vector<long long> v[NR + 10];
long long cnt[MR + 10];
int main(){
long long T;
read(T);
while(T--){
long long n;
read(n);
for(long long i = 1;i <= n;i++){
v[i].clear();
long long k;
read(k);
for(long long j = 1;j <= k;j++){
long long x;
read(x);
v[i].emplace_back(x);
}
}
for(long long i = 1;i <= n;i++){
for(auto it : v[i]){
cnt[it]++;
}
}
bool ans = false;
for(long long i = 1;i <= n;i++){
bool flag = true;
for(auto it : v[i]){
if(cnt[it] <= 1){
flag = false;
break;
}
}
ans |= flag;
}
for(long long i = 1;i <= n;i++){
for(auto it : v[i]){
cnt[it]--;
}
}
printf("%s\n", ans ? "Yes" : "No");
}
return 0;
}
Interesting Sequence
思路:
PS:
l
o
w
b
i
t
(
x
)
lowbit(x)
lowbit(x) 的意义是
x
x
x 的二进制位下最低为的一所代表的十进制值
PS2:$ lowbit(x)=x\wedge(-x)$
可以看出:若有解时 x ≤ n x \le n x≤n(与不能增加,只能减少), 且若有一位 n n n 上为 0 0 0 而 x x x 为 1 1 1 时,必定没有解( 0 ∧ 1 = 0 0 \wedge 1 = 0 0∧1=0 )。
并能由
0
∧
1
=
0
0 \wedge 1 = 0
0∧1=0 得出,一个数
k
k
k 与运算任何在范围
k
+
1
≤
p
≤
k
+
l
o
w
b
i
t
(
k
)
k + 1 \le p \le k + lowbit(k)
k+1≤p≤k+lowbit(k) 内的数
p
p
p 进行与运算都等于
k
k
k ,所以答案是若干次 n += lowbit(n)
后的
n
n
n。
PS3000: ∧ \wedge ∧ 为 逻辑与
代码:
#include<bits/stdc++.h>
using namespace std;
const int NR = 1e3;
long long a[NR + 10], b[NR + 10];
long long lowbit(long long x){
return x & (-x);
}
void solve(){
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
long long n, x;
scanf("%lld%lld", &n, &x);
long long tn = n, tx = x;
while(tn){
a[++a[0]] = tn % 2ll;
tn /= 2ll;
}
while(tx){
b[++b[0]] = tx % 2ll;
tx /= 2ll;
}
for(int i = 1;i <= max(a[0], b[0]);i++){
if(a[i] != b[i] && !a[i]){
printf("-1\n");
return ;
}
}
long long tmp = n;
while(tmp != x){
n += lowbit(n);
tmp &= n;
if(tmp < x){
printf("-1\n");
return ;
}
}
printf("%lld\n", n);
}
int main(){
int T;
scanf("%d", &T);
while(T--){
solve();
}
return 0;
}