Codeforces Round741

A:
传送门
思路:
当a小于b的一半的时候,那么最大的结果就是b%(b/2b+1)
当a大于b的一半,最大值就是b%a
代码:

#include<bits/stdc++.h>
using namespace std;
int t,a,b;
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>a>>b;
        if(a<=b/2)cout<<b-b/2-1<<endl;
        else
        cout<<b%a<<endl;
    }
    return 0;
}

B:
传送门
很明显可以发现,最终的大于一位合数一定是由2 3 5 7组成的,而且最多只有两位
代码:

#include <bits/stdc++.h>
using namespace std;
int t;
int k;
string s;
int cnt[15];
bool check(int x)
{
    if (x == 1)
        return 1;
    for (int i = 2; i * i <= x; i++)
    {
        if (x % i == 0)
            return 1;
    }
    return 0;
}
int main()
{
    cin >> t;
    while (t--)
    {
        cin >> k;
        cin >> s;
        memset(cnt, 0, sizeof(cnt));
        bool flag = false;
        for (int i = 0; i < k; i++)
        {
           if(check(s[i]-'0'))
           {
               cout<<1<<endl;
               cout<<s[i]-'0'<<endl;
               flag=true;
               break;
           }
        }
        if(!flag){
        for (int i = 0; i <= k; i++)
        {
            for (int j = i + 1; j < k; j++)
            {
                if (check((s[i] - '0') * 10 + (s[j] - '0')))
                {
                    cout << 2 << endl;
                    cout<< s[i] << s[j] << endl;
                    flag = true;
                    break;
                }
            }
            if (flag)
                break;
        }
        }
        
    } 

return 0;
}

C:
传送门
思路:找任意0的位置,两个二进制数,其余部分一样,其中某一个在开头或者结尾加一个0,最终表示为十进制后两个一定是满足倍数关系的
如果没有0,根据n的奇偶判断,n是偶数可以任意选,n是奇数不选最后一位就可以
代码:

#include<bits/stdc++.h>
using namespace std;
int t,n;
string s;
int main()
{
    cin>>t;
    while(t--)
    {   cin>>n;
        cin>>s;
        int ind=-1;
        for(int i=1;i<=n;i++)
        {
            if(s[i-1]=='0')
            {
                ind=i;
                break;
            }
        }
        if(ind==-1)
        {
            cout << 1 <<" " << ((n & 1) ? n - 1 : n) << " " << 1 << " " << n / 2 << endl;
        }
        
        else if(ind<=n/2)
        {
            cout<<ind<<" "<<n<<" "<<ind+1<<" "<<n<<endl;
        }
        else 
        {
            cout<<1<<" "<<ind<<" "<<1<<" "<<ind-1<<endl;
        }
    }
    return 0;
}

D1D2,只放d2的链接和代码
传送门
结论:查询的长度为奇数,最终结果一定是1,查询长度为偶数,最终结果是0或者2
证明:奇数长度的值一定是奇数,因为有奇数个+1或者-1加减,得到的结果还是-1,任意的奇数都可以表示为2*x+1,删掉某一个,删去的这一个对结果的影响变为0,后边的影响变成-x,找这样的位置删除就可以,所以可以推出一个式子 pre[r]-pre[i]=pre[i-1]-pre[l-1],即pre[l]+pre[r]=pre[i]+pre[i-1],二分查就可以了
偶数的情况:如果pre[r]-pre[l-1]=0,那么就不需要删除,否则,删掉左端点,剩下的长度又变成奇数,按奇数串处理即可
代码:

#include <bits/stdc++.h>
#define all(x) x.begin(), x.end()
using namespace std;
const int N = 1e6 + 10;
int t, n, q;
typedef vector<int> vi;
char s[N];
int pre[N];
/*void solve(int l, int r)
{
    int ans = pre[r] + pre[l - 1];

    int pos = mp[ans][lower_bound(mp[ans].begin(), mp[ans].end(), l) - mp[ans].begin()];
    cout << pos << endl;
    return;
}*/
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(nullptr);
    cin >> t;
    while (t--)
    {
        map<int, vector<int>> mp;
        cin >> n >> q;
        cin >> s+1;
        for (int i = 1; i <= n; i++)
        {
             pre[i] = pre[i - 1] + (s[i] == '+' ? 1 : -1) * ((i & 1) ? 1 : -1);
            mp[pre[i - 1] + pre[i]].push_back(i);
        }
        while (q--)
        {
            int l, r;
            cin >> l >> r;
            int len = r - l + 1;
            if (len & 1)
            {
                cout << 1 << "\n";
                if (l == r)
                {
                    cout << l << "\n";
                }
                else
                {
                    int ans = pre[r] + pre[l - 1];

                    int pos = mp[ans][lower_bound(mp[ans].begin(), mp[ans].end(), l) - mp[ans].begin()];
                    cout << pos << "\n";
                }
            }
            else
            {
                if (pre[r] - pre[l - 1] == 0)
                    cout << 0 << "\n";
                else
                {
                    cout << 2 << "\n";
                    cout << l << " ";
                    if (l + 1 == r)
                        cout << r << "\n";
                    else
                    {
                        int ans = pre[r] + pre[l];

                        int pos = mp[ans][lower_bound(mp[ans].begin(), mp[ans].end(), l + 1) - mp[ans].begin()];
                        cout << pos << "\n";
                    }
                }
            }
        }
    }
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值