A. Two Subsequences
题意:
给你一个字符串 s。您需要找到两个非空字符串 a 和 b,以满足以下条件:
字符串 a 和 b 都是 s 的子序列。
对于每个索引 i,字符串 s 的字符 si 必须恰好属于字符串 a 或 b 之一。
字符串 a 是字典序最小可能的;字符串 b 可以是任何可能的字符串。
给定字符串 s,打印任何有效的 a 和 b。
题解:
字典序最小当然就是s中的最小字母了,b可以是任意,那么就是s减去a后的字符串了
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
string s;
cin >> s;
int pos = 0;
for (int i = 0; i < s.size(); ++i)
{
if (s[i] < s[pos])
{
pos = i;
}
}
string ans = "";
for (int i = 0; i < s.size(); ++i) if (i != pos)
{
ans += s[i];
}
cout << s[pos] << " " << ans << endl;
}
return 0;
}
B. Divine Array
题意:
有一个数组a,现在对其进行变换,将第i个位置上的数字a[i]变成a[i]的出现次数。
给出q个询问,每个询问给出x,k,代表第k次变换后,a[x]的值为多少?
题解:
在经过一定的变换次数后,整个数组会保持不变,所以可以在询问前预处理出所有的情况。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin >> t;
while (t--)
{
string s;
cin >> s;
int pos = 0;
for (int i = 0; i < s.size(); ++i)
{
if (s[i] < s[pos])
{
pos = i;
}
}
string ans = "";
for (int i = 0; i < s.size(); ++i) if (i != pos)
{
ans += s[i];
}
cout << s[pos] << " " << ans << endl;
}
return 0;
}
C. Array Elimination
题意:
每次选k个数,令x=a[1]&a[2]&a[3]......a[k], 并且a[1] - x, a[2] - x .... a[k] - x, 问是否能将数组a的所有元素变为0,从小到大输出所有k的可能值。
题解:
把所有数都变为0,也就是将所有数的数位变为0。每次操作,减去的是k个数的与值。所以,为了将一个数位变为0,减去的这个与值的该数位也要为0。为了让与值的该数位为0,那么挑选的k个位置上的数该数位都为1。
因为可以操作若干次,所以对于一列数位的x个1来说,可以选择x的因子y个1,能够将这y个数的该数位都化为0,然后进行若干次。
综合考虑所有数位,那么满足条件的 k 就为30个数位中,1的个数的所有公约数。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxx=2e5+10;
int a[maxx];
int b[maxx];
int gcd(int a,int b)
{
if(!b)
return a;
return gcd(b,a%b);
}
int main()
{
int t,n;
cin>>t;
while(t--)
{
memset(b,0,sizeof(b));
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
for(int j=0;j<=30;j++)
{
if((a[i]>>j)&1)
{
int p=a[i]>>j;
int pp=(a[i]>>j)&1;
//cout<<a[i]<<" "<<j<<" "<<p<<" "<<pp<<endl;
b[j]++;
}
}
}
int x=0;
for(int i=0;i<=30;i++)
{
if(b[i])
x=gcd(x,b[i]);
}
for(int i=1;i<=n;i++)
{
if(x%i==0)
{
cout<<i<<" ";
}
}
cout<<endl;
}
}