周行新春码拉松第二赛道——题解+代码

本题解参加2021周行新春码拉松
比赛链接

Problem.A 等差数列

题解

我们需要知道等差数列前n项和的第二个公式,不知道的话直接手推也行。
公式: S n = n ∗ a 1 + n ∗ ( n − 1 ) ∗ d 2 S_{n}=n*a_{1}+\frac{n*(n-1)*d}{2} Sn=na1+2n(n1)d
公式里面的 d = a 2 − a 1 d=a_{2}-a_{1} d=a2a1,然后直接带入公式即可。
trick:数据范围会爆int,注意开long long。

代码

#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
    return a/gcd(a,b)*b;
}
inline int read(){
    int s=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*f;
}
const int N = 1e5+7;
int a[N];
void solve(){
    ll a1,a2,n;scl(a1);scl(a2);scl(n);
    cout<<n*a1+n*(n-1)/2*(a2-a1)<<endl;
}
int main(){
    //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    //debug = 1;
#endif
    //time_t beg, end;
    //if(debug) beg = clock();

    int T=1;
    while(T--) solve();

    /*
    if(debug) {
        end = clock();
        printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
    }
    */
    return 0;
}

Problem.B 士兵选择

题解

数据范围给的比较小,我们直接枚举两个士兵就行了。
比较好的做法是先对士兵进行排序(按照身高从低低到高)
然后先 O ( n ) O(n) O(n)枚举当前士兵 a [ i ] a[i] a[i],二分出大于当前士兵身高 + d +d +d的第一个士兵的下标 i d id id,不难发现 [ i + 1 , i d ] [i+1,id] [i+1,id]范围的士兵都满足条件,最后不要忘记乘2就行了。
这里给出二分的代码

代码

#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
    return a/gcd(a,b)*b;
}
inline int read(){
    int s=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*f;
}
const int N = 1e5+7;
int a[N];
void solve(){
    int n=read(),d=read();
    rp(i,1,n) a[i]=read();
    sort(a+1,a+1+n);
    int ans=0;
    rp(i,1,n){
        int id=upper_bound(a+1,a+1+n,a[i]+d)-a;
        id--;
        id=min(id,n);
        ans+=id-i;
    }
    cout<<ans*2<<endl;
}
int main(){
    //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    //debug = 1;
#endif
    //time_t beg, end;
    //if(debug) beg = clock();

    int T=1;
    while(T--) solve();

    /*
    if(debug) {
        end = clock();
        printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
    }
    */
    return 0;
}

Problem.C 递增序列

题解

从前往后贪心的加就行了,每当遇到下一个数比当前数小,就对下一个数进行加 d d d的操作,知道下一个数比当前数大

代码

#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
    return a/gcd(a,b)*b;
}
inline int read(){
    int s=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*f;
}
const int N = 1e5+7;
ll a[N],d;
void solve(){
    int n=read();
    scl(d);
    rp(i,1,n) scl(a[i]);
    ll ans=0;
    rp(i,2,n){
        if(a[i]<=a[i-1]){
            ll num=(a[i-1]-a[i])/d+1;
            a[i]+=num*d;
            ans+=num;
            // outval2(i,num);
        }
    }
    cout<<ans<<endl;
}
int main(){
    //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    //debug = 1;
#endif
    //time_t beg, end;
    //if(debug) beg = clock();

    int T=1;
    while(T--) solve();

    /*
    if(debug) {
        end = clock();
        printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
    }
    */
    return 0;
}

Problem.D Easy Problem

题解

当字符串中字符的最大出现次数为 1 1 1且字符串长度不等于 1 1 1时,输出 N O NO NO,否则输出 Y E S YES YES

代码

#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
    return a/gcd(a,b)*b;
}
inline int read(){
    int s=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*f;
}
const int N = 1e5+7;
int cnt[26];
/*
aaabbbcccd
*/
void solve(){
    string s;cin>>s;
    int len=s.size();
    rp(i,0,len-1) cnt[s[i]-'a']++;
    int Max=0;
    rp(i,0,25) Max=max(cnt[i],Max);
    if(Max==1&&len!=1) pN;
    else pY;
}
int main(){
    //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    //debug = 1;
#endif
    //time_t beg, end;
    //if(debug) beg = clock();

    int T=1;
    while(T--) solve();

    /*
    if(debug) {
        end = clock();
        printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
    }
    */
    return 0;
}

Problem.E 数列

题解

加上当前位置开始填 1 1 1,那么从前位置开始连续 1 1 1的长度就是从当前位置开始到遇到的第一个填 0 0 0的位置 − 1 -1 1 0 0 0的情况类似。
那么直接按照模拟枚举就行了。
注意最后一部分到n截止的情况。

代码

#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
    return a/gcd(a,b)*b;
}
inline int read(){
    int s=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*f;
}
const int N = 1e6+7;
struct node{
    int pos,op;
}p[N];
void solve(){
    int m=read(),n=read();
    int ans1=0,ans2=0;
    rp(i,1,m) p[i].pos=read(),p[i].op=read();
    rp(i,1,m){
        int cur_op=p[i].op;
        int cur_pos=p[i].pos;
        while(i+1<=m&&p[i+1].op==cur_op) i++;
        if(i==m){
            if(cur_op==1) ans1=max(ans1,n-cur_pos+1);
            else ans2=max(ans2,n-cur_pos+1);
        }
        else{
            if(cur_op==1) ans1=max(ans1,p[i+1].pos-cur_pos);
            else ans2=max(ans2,p[i+1].pos-cur_pos);
        }
    }
    cout<<ans1<<" "<<ans2<<endl;
}
int main(){
    //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    //debug = 1;
#endif
    //time_t beg, end;
    //if(debug) beg = clock();

    int T=1;
    while(T--) solve();

    /*
    if(debug) {
        end = clock();
        printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
    }
    */
    return 0;
}

Problem.F DNA

题解

m a p map map维护每个 D N A DNA DNA序列的个数,然后枚举每个 D N A DNA DNA序列,判断是否存在与它匹配的序列,有的话答案加一,并且在 m a p map map中减去它们自身所占的数量。
trick:枚举时不仅要判断是否存在与之匹配的 D N A DNA DNA序列,还要判断当前枚举的 D N A DNA DNA序列是否已经被之前匹配删除过。

代码

#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
    return a/gcd(a,b)*b;
}
inline int read(){
    int s=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*f;
}
const int N = 1e5+7;
map<string,int> mp;
string s[N];
void solve(){
    int n=read();
    rp(i,1,n){
        cin>>s[i];
        mp[s[i]]++;
    }
    int ans=0;
    rp(i,1,n){
        int len=s[i].size();
        string ss="";
        rp(j,0,len-1){
            if(s[i][j]=='A') ss+="T";
            if(s[i][j]=='T') ss+="A";
            if(s[i][j]=='G') ss+="C";
            if(s[i][j]=='C') ss+="G";
        }
        if(ss==s[i]){
            if(mp.find(ss)!=mp.end()&&mp[ss]>=2){
                mp[ss]-=2;
                ans++;
            }
        }
        else if(mp.find(ss)!=mp.end()&&mp[ss]>=1&&mp[s[i]]>=1){
            mp[ss]--;
            mp[s[i]]--;
            ans++;
        }
    }
    cout<<ans<<endl;
}
int main(){
    //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    //debug = 1;
#endif
    //time_t beg, end;
    //if(debug) beg = clock();

    int T=1;
    while(T--) solve();

    /*
    if(debug) {
        end = clock();
        printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
    }
    */
    return 0;
}

Problem.G 三棱锥

题解

手推几个数据,然后oeis一发,第一个符合的就是公式,然后按照公式输出即可。
正解应该是dp,算是比较常见的dp,前面题解也给出了dp的解法。
注意取模要考虑逆元

代码

#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
    return a/gcd(a,b)*b;
}
inline int read(){
    int s=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*f;
}
const ll mod = 1e9+7;
const int N = 1e5+7;
int a[N];
ll quickPow(ll a, ll b, ll mod) {
    ll ans = 1;
    while(b) {
        if(b&1) ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans;
}
void solve(){
    ll n;scl(n);
    if(n&1) cout<<(quickPow(3,n,mod)%mod-3+mod)%mod*quickPow(4,mod-2,mod)%mod<<endl;
    else cout<<(quickPow(3,n,mod)%mod+3+mod)%mod*quickPow(4,mod-2,mod)%mod<<endl;
}
int main(){
    //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    //debug = 1;
#endif
    //time_t beg, end;
    //if(debug) beg = clock();

    int T=1;
    while(T--) solve();

    /*
    if(debug) {
        end = clock();
        printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
    }
    */
    return 0;
}

Problem.H 异或

题解

第二赛道最有意思的一道题,不过算是经典题(cf上的一道原题)。
前面已经有讲的比较好的题解了,这里就大致说一下这个巧妙的思路,以及怎么去往这个思路想。
首先暴力的做法肯定过不了,然后考虑进行优化,优化的思路需要从 x + y = a x+y=a x+y=a x ⨁ y = b x \bigoplus y=b xy=b这两个方程入手。
异或其实就是不进位的加法,这样就保证了 a > = b a>=b a>=b,那么当 a < b a<b a<b的情况时直接输出 − 1 -1 1即可。
根据第二个方程我们拆位进行考虑两种情况,
1.当 b b b的第 i i i位为 1 1 1时, x x x y y y的第 i i i位只能一个为 0 0 0,一个为 1 1 1,因为我们需要保证 x x x最小,所以当 b b b的第 i i i位为 1 1 1时, x x x的第 i i i位只能为 0 0 0 y y y的第 i i i位只能为 1 1 1
这时我们可以发现根据第一种情况确定出来的 y y y就是 b b b,那么 a − b a-b ab就是我们在第二种情况需要确定之后的和。
2.当 b b b的第 i i i位为 0 0 0的情况时,此时由分成了两种情况:
2.1 第 i i i位都为 0 0 0
2.2 第 i i i位都为 1 1 1
这时我们发现只利用第二个方程解决确定不了,我们就需要引入第一个方程进行考虑,在第 i i i位都为 0 0 0时,对第一个方程的结果没有影响,在第 i i i位都为 1 1 1时,使得第一个方程的结果多了一个 2 i + 1 2^{i+1} 2i+1
那么现在问题转换成了给你一个数 c c c(等于 a − b a-b ab),是否能够选出一些位(第 i i i位只能全为 1 1 1或者 0 0 0,全为 1 1 1的情况产生的结果为 2 i 2^{i} 2i),使得这些位凑出来的结果为 c c c
这时可以直接选择贪心从高位往低位放。
也可以选择往下继续找规律。
因为我们每次对答案的贡献都是 2 2 2的次幂。
那么最终 c c c肯定需要是一个偶数,对于奇数的情况直接输出-1。
再手推几个数据可以发现 c 2 \frac{c}{2} 2c就是我们求的x。
最后我们就根据确定出来的 x x x y y y判断一下是否符合第二个方程就行了。

代码

#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
    return a/gcd(a,b)*b;
}
inline int read(){
    int s=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*f;
}
void solve(){
    ll a,b;cin>>a>>b;
    if(a<b){
        puts("-1");
        return ;
    }
    ll c=a-b;
    if(c&1){
        puts("-1");
        return ;
    }
    ll x=c/2;
    ll y=a-x;
    if((x^y)!=b) puts("-1");
    else cout<<x<<" "<<y<<endl;
}
int main(){
    //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
    // freopen("in.txt", "r", stdin);
    //debug = 1;
#endif
    //time_t beg, end;
    //if(debug) beg = clock();

    int T=1;
    while(T--) solve();

    /*
    if(debug) {
        end = clock();
        printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
    }
    */
    return 0;
}

Problem.I Hard Problem I

题解

根据贪心的策略发现直接修改奇数位置的字符最优(下标从 0 0 0开始),那么我们直接枚举奇数位置的字符,如果和前面或者后面的字符相同,那么就直接修改成和相邻字符不同的任意一个其他字符。

代码

#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
    return a/gcd(a,b)*b;
}
inline int read(){
    int s=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*f;
}
const int N = 1e6+7;
struct node{
    int pos,op;
}p[N];
void solve(){
    string s;cin>>s;
    int len=s.size();
    int num=0;
    rp(i,1,len-1){
        if(s[i]==s[i-1]){
            if(i!=len-1){
                int id1=s[i-1]-'a';
                int id2=s[i+1]-'a';
                // outval3(i,id1,id2);
                rp(j,0,25){
                    if(j!=id1&&j!=id2){
                        s[i]=j+'a';
                        break;
                    }
                }
            }
            num++;
        }
    }
    // outval(s);
    cout<<num<<endl;
}
int main(){
    //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    //debug = 1;
#endif
    //time_t beg, end;
    //if(debug) beg = clock();

    int T=1;
    while(T--) solve();

    /*
    if(debug) {
        end = clock();
        printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
    }
    */
    return 0;
}

Problem.J 消息传播

题解

手推几个样例可以发现,当 [ 2 , n + 1 ] [2,n+1] [2,n+1]中有能整除 k + 1 k+1 k+1的或者被 k + 1 k+1 k+1整除的数时输出2,否则输出1。
那么问题就转换成了怎么快速判断 [ 2 , n + 1 ] [2,n+1] [2,n+1]中是否存在符合条件的数。
我们把符合条件的数分成两种:
1.被 k + 1 k+1 k+1整除的数。
2.整除 k + 1 k+1 k+1的数。
对于第一种情况我们直接判断 2 ∗ ( k + 1 ) 2*(k+1) 2(k+1)是否小于等于 n n n即可,因为 2 ∗ ( k + 1 ) 2*(k+1) 2(k+1)是最小的被 k + 1 k+1 k+1整除的数。
对于第二中情况我们直接判断 k + 1 k+1 k+1是不是质数即可,不是质数的话,根据唯一分解定理,在 [ 2 , n + 1 ] [2,n+1] [2,n+1]中肯定存在能够整除 k + 1 k+1 k+1的数。

代码

#include <bits/stdc++.h>
#define PI atan(1.0)*4
#define rp(i,s,t) for (register int i = (s); i <= (t); i++)
#define RP(i,t,s) for (register int i = (t); i >= (s); i--)
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset(a,b,sizeof(a))
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define m_p make_pair
#define p_b push_back
#define ins insert
#define era erase
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define dg if(debug)
#define pY puts("YES")
#define pN puts("NO")
#define outval(a) cout << "Debuging...|" << #a << ": " << a << "\n";
#define outval2(a,b) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b << "\n";
#define outval3(a,b,c) cout << "Debuging...|" << #a << ": " << a <<"\t"<< #b << ": " << b <<"\t"<< #c << ": " << c << "\n";
using namespace std;
int debug = 0;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b){
    return a/gcd(a,b)*b;
}
inline int read(){
    int s=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        s=s*10+ch-'0';
        ch=getchar();
    }
    return s*f;
}
int isprime(ll x){
    for(ll i=2;i*i<=x;i++) if(x%i==0) return 0;
    return 1;
}
void solve(){
    ll n,k;scl(n);scl(k);k++;n++;
    if(isprime(k)&&k*2>n) puts("1");
    else puts("2");
}
int main(){
    //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt", "r", stdin);
    //debug = 1;
#endif
    //time_t beg, end;
    //if(debug) beg = clock();
    int T=1;
    while(T--) solve();

    /*
    if(debug) {
        end = clock();
        printf("time:%.2fs\n", 1.0 * (end - beg) / CLOCKS_PER_SEC);
    }
    */
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值