这两场打的还算可以。
Round #751
A题
- 题意
把字符串 s s s 拆分成两个串 a a a、 b b b,使得 a a a < b b b。 - 思路
把 a a a 直接等于 s s s 中出现的最小的字母就行,其他的全给 b b b。 - 代码
void solve()
{
string s;cin>>s;
char a = 'z';
bool flag = 1;
for(int i = 0;i < s.size();i ++){
if(s[i] < a){
a = s[i];
}
}
cout<<a<<" ";
for(int i = 0;i < s.size();i ++){
if(s[i] == a&&flag == 1){
flag = 0;
}
else cout<<s[i];
}cout<<endl;
}
B题
-
题意
关键就是每次操作 a j = c n t [ a j ] a_j = cnt[a_j] aj=cnt[aj] ,就是把第 j j j 个位置变成 a j a_j aj 在整个序列中出现的次数。 -
思路
感觉操作到一定次数后,序列肯定会保持不变。所以直接模拟 -
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10,mod=1e9+7;
template<typename T>
void Debug(T x,string s){
cout<<s<<": "<<x<<endl;
}
#define PII pair<int,int>
#define x first
#define y second
#define PB push_back
// int a[N],b[N];
int cnt[2005];
void solve()
{
int n;cin>>n;
memset(cnt,0,sizeof cnt);
vector<int> a(n+1);
for(int i = 1;i <= n;i ++) cin>>a[i],cnt[a[i]]++;
vector<vector<int> > ans;
ans.push_back(a);
int c_t = 0;
while(1){
bool flag = 1;
vector<int> vec(n+1);
for(int i = 1;i <= n;i ++){
vec[i] = cnt[a[i]];
}
// for(int i = 1;i <= n;i ++){
// cout<<vec[i]<<" ";
// }cout<<endl;
for(int i = 1;i <= n;i ++){
if(vec[i] != a[i]){
flag = 0;break;
}
}
if(flag) break;
else{
memset(cnt,0,sizeof cnt);
c_t ++;
for(int i = 1;i <= n;i ++) a[i] = vec[i],cnt[a[i]]++;
ans.push_back(vec);
}
}
int q;cin>>q;
while(q--){
int tx,tk;cin>>tx>>tk;
// cout<<tx<<" "<<tk<<endl;
tk = min(tk,c_t);
cout<<ans[tk][tx]<<endl;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.txt", "r", stdin);
freopen("aout.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
solve();
}
白 r e re re 了一发。
C题
- 题意
- 思路
肯定是每一个二进制位的 1 1 1 的数量的 g c d gcd gcd,然后 g c d gcd gcd 的全部因数。 - 代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10,mod=1e9+7;
template<typename T>
void Debug(T x,string s){
cout<<s<<": "<<x<<endl;
}
#define PII pair<int,int>
#define x first
#define y second
#define PB push_back
int a[N],b[N];
void solve()
{
int n;cin>>n;
for(int i = 1;i <= n;i ++) cin>>a[i];
sort(a+1,a+1+n);
if(a[n] == 0){
for(int i = 1;i <= n;i ++){
cout<<i<<" ";
}cout<<endl;return;
}
int gcd = 0;//注意一开始不能把他直接赋值 n .又白wa了一发。
for(int i = 0;i <= 31; i ++){
int c_t = 0;
for(int j = 1;j <= n;j ++){
if((a[j]>>i)&1==1) c_t ++;
}
if(c_t){
if(!gcd) gcd = c_t;
else gcd = __gcd(gcd,c_t);
}
}
set<int> ans;
for(int i = 1;i*i <= gcd;i ++){
if(gcd%i==0){
ans.insert(i);ans.insert(gcd/i);
}
}
for(auto &ii:ans){
cout<<ii<<" ";
}cout<<endl;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.txt", "r", stdin);
freopen("aout.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
solve();
}
Round #750
A题
- 思路
好像直接把和算出来判断奇偶就可以了,比赛的时候猜出来了,不敢直接写,分类讨论了一下。 - 代码
void solve()
{
ll a,b,c;
cin>>a>>b>>c;
if(c&1){
if(b&1){
if(a&1){
cout<<0<<endl;
}
else{
cout<<1<<endl;
}
}
else{
if(a&1){
cout<<0<<endl;
}
else{
cout<<1<<endl;
}
}
}
else{
if(b&1){
if(a%2==0){
cout<<0<<endl;
}
else{
cout<<1<<endl;
}
}
else{
cout<<(a%2)<<endl;
}
}
}
其实一行代码就搞定了
cout<<(a+b*2+c*3)%2<<endl;
B题
-
思路
序列中 1 1 1 的个数乘以 2 2 2 的 0 0 0 的个数 的幂次。
简单解释一下:想让出现 s − 1 s-1 s−1,那必然这个子序列中有且仅有一个 1 1 1,对于整个序列中出现的 c n t 0 cnt0 cnt0 个 0 0 0 ,可以任意挑选任意个 0 0 0,那么就是 2 c n t 0 2^{cnt0} 2cnt0 个。 -
代码
void solve()
{
int n;cin>>n;
int cnt1 = 0,cnt0 = 0;
for(int i = 1;i <= n;i++) {
cin>>a[i];
if(a[i] == 0) cnt0++;
if(a[i] == 1) cnt1++;
}
ll ans = 1;
for(int i = 1;i <= cnt0;i ++) ans*=2;
cout<<ans*cnt1<<endl;
}
C题
-
题意
删除字符串中某一个字母的 s o m e some some,使得删除后是回文串。 -
思路
枚举是哪一个字母,然后双指针扫这个字符串。取最小。 -
代码
void solve()
{
int n;cin>>n;
string s;cin>>s;
int ans = s.size()+1;
for(int i = 0;i < 26;i ++){
int tans = 0;
char tx = 'a'+i;
int l = 0,r = s.size()-1;
bool flag = true;
while(l<r){
if(s[l]==s[r]){
l++;r--;
}
else{
if(s[l]!=tx&&s[r]!=tx){
flag = false;break;
}
else if(s[l]==tx){
while(s[l]==tx){
tans++;l++;
}
}
else if(s[r] == tx){
while(s[r] == tx){
tans++;r--;
}
}
}
}
if(flag){
ans = min(tans,ans);
}
}
if(ans == s.size()+1){
cout<<-1<<endl;
}
else{
cout<<ans<<endl;
}
}
D题
- 题意
- 思路
如果是偶数的话,直接对应相消就行。就假如:
a b c d
-c -d a b
如果是奇数的话,转换成偶数之后还剩 3 3 3 个。>
a b c
b+c -a - a
这样就可以把这三个数消掉,但是题目要求不能出现 0 0 0,所以 要判断是否 b + c = = 0 b+c==0 b+c==0,也可以 a + c a+c a+c、 a + b a+b a+b;所以判断一下就可以。
- 代码
void solve()
{
int n;cin>>n;
for(int i = 1;i <= n;i ++){
cin>>a[i];
}
if(n&1){
if(n==3){
int xa = a[n/2],xb = a[n/2+2],xc = a[n/2+1];
if(xa+xb!=0){
cout<<-xc<<" "<<xa+xb<<" "<<-xc<<" ";
}
else if(xa+xc!=0){
cout<<-xb<<" "<<-xb<<" "<<xa+xc<<" ";
}
else if(xb+xc!=0){
cout<<xb+xc<<" "<<-xa<<" "<<-xa<<" ";
}
cout<<endl;
}
else{
for(int i = n/2+3;i <= n;i ++){
cout<<-a[i]<<" ";
}
int xa = a[n/2],xb = a[n/2+2],xc = a[n/2+1];
if(xa+xb!=0){
cout<<-xc<<" "<<xa+xb<<" "<<-xc<<" ";
}
else if(xa+xc!=0){
cout<<-xb<<" "<<-xb<<" "<<xa+xc<<" ";
}
else if(xb+xc!=0){
cout<<xb+xc<<" "<<-xa<<" "<<-xa<<" ";
}
for(int i = 1;i <= n/2-1;i ++){
cout<<a[i]<<" ";
}cout<<endl;
}
}
else{
for(int i = n/2+1;i <= n;i ++){
cout<<-a[i]<<" ";
}
for(int i = 1;i <= n/2;i ++){
cout<<a[i]<<" ";
}cout<<endl;
}
}
当时以为这题很难来,白 w a wa wa 了两发,以后交题得仔细想想。