练习

A. Common Subsequence

https://codeforces.com/contest/1382/problem/A

题意:

给出两个数组,要求找到最短的公共子序列

解决:

建个map存一下出现的数字,如果有相同的就直接输出"YES",没有就是"NO"

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=2e5+1000;
ll t,n,m,a[maxn],b[maxn];
map<ll,ll> ch;
int main(){
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        cin>>n>>m;
        for(int i=0;i<n;i++){
            cin>>a[i];
            ch[a[i]]++;
        }
        ll res=-1;
        for(int i=0;i<m;i++){
            cin>>b[i];
            if(ch[b[i]]!=0){
                res=a[i];
            }
        }
        ch.clear();
        if(res==-1) cout<<"NO"<<endl;
        else cout<<"YES"<<endl<<1<<' '<<res<<endl;
    }
    return 0;
}

B. Sequential Nim

https://codeforces.com/contest/1382/problem/B

题意:

给出若干石堆,有两个人轮流从非空的石堆中取出正整数个石子,每个人都采取最优策略,最终第一次遇到空石堆的人输。

分析:

可以看出,谁先轮到最后一堆谁就获胜;每个人可以通过让一个非1的石堆剩余一个来让对手强制选取,故一个非1的石堆不改变先手顺序;对于多个1的情况,如果1的前面有大于1的石堆,那么不论有几个1,选手在非1的那个石堆可以全拿或者剩一个来改变顺序,所以这些1都是无效的,那么就只需要考虑最前面的1的个数,同时忽略最后一个数。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=2e5+1000;
ll t,n,m,a[maxn],b[maxn];
map<ll,ll> ch;
int main(){
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        cin>>n;
        ll con=0;
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        for(int i=0;i<n-1;i++){
            if(a[i]==1){
                con++;
            }
            if(a[i]!=1) break;
        }
        if(con&1) cout<<"Second"<<endl;
        else cout<<"First"<<endl;
    }
    return 0;
}

A. Common Prefixes

https://codeforces.com/contest/1384/problem/A

题意:

给出n个元素的数组,要求给出n+1个字符串使得第i个和第i+1个字符串的公共前缀长度为\(a_i\)

分析:

第一个直接全给\(a\),之后每次都增加一个就可以,当增加到\(z\)时在变成\(a\)就可以了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const ll maxn=2e5+1000;
const ll inf=0x3f3f3f3f;
ll t,n,k,z,a[maxn];
int main(){
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        cin>>n;
        for(int i=0;i<n;i++)cin>>a[i];
        string s(50,'a');
        cout<<s<<endl;
        for(int i=0;i<n;i++){
            s[a[i]]++;
            if(s[a[i]]=='z')s[a[i]]='a';
            cout<<s<<endl;
        }
    }
    return 0;
}

A. Acacius and String

https://codeforces.com/contest/1379/problem/A

题意:

给出一个字符串含有'?',要求是否可以通过将所有的'?'换为任意字母使得"abacaba"在改变后的字符串中只出现一次。

分析:

先对于原本的字符串进行判断,如果存在两个及以上那就不行;如果只存在一个那就可以,输出的时候直接把?
改成x就行;如果不存在那就再判断是否可以通过替换得到。
替换时先判断某一段字符能否替换,如果可以,那就替换然后再当作原本的字符串判断,然后回溯并判断下一个位置,我写的比较烦,应该有更简洁的写法。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=2e5+1000;
ll t,n,m;
string a;
bool yes2(int index){
    string b="abacaba";
    int ch=0;
    for(int i=0;i<b.size();i++){
        if(a[index+i]==b[i]){
            ch++;
        }
    }
    return ch==b.size();
}
bool yes1(int index){
    string b="abacaba";
    ll pos[10];
    int ch=0;
    fill(pos,pos+10,0);
    for(int i=0;i<b.size();i++){
        if(a[index+i]==b[i]||a[index+i]=='?'){
            ch++;
            if(a[index+i]=='?'){
                pos[i]++;
            }
        }
    }
    if(ch==7){
        for(int i=0;i<b.size();i++){      
            if(a[index+i]=='?'){
                a[index+i]=b[i];
                pos[i]++;
            }
        }
        ll num=0;
        for(int i=0;i<a.size();i++){
            if(yes2(i)) num++;
        }if(num==1) return 1;
        else{
            for(int i=0;i<b.size();i++){
                if(pos[i]){
                    a[index+i]='?';
                }
            }
            if(index+1<a.size())
                return yes1(index+1);
            else 
                return 0;
        }
    }else{
        if(index+1<a.size())
            return yes1(index+1);
        else 
            return 0;
    } 
}
int main(){
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>t;
    int no;
    while(t--){
        cin>>no;
        cin>>a;
        ll num1=0,num2=0;
        for(int i=0;i+6<a.size();i++){
            if(yes2(i)){
                num2++;
            }
        }
        if(num2>=2) cout<<"No"<<endl;
        else if(num2==1){
            cout<<"Yes"<<endl;
            for(int i=0;i<a.size();i++){
                if(a[i]=='?') cout<<'x';
                else cout<<a[i];
            }cout<<endl;
        }else{
            if(yes1(0)) {
                cout<<"Yes"<<endl;
                for(int i=0;i<a.size();i++){
                    if(a[i]=='?'){
                        cout<<'x';
                    }else cout<<a[i];
                }cout<<endl;
            }
            else cout<<"No"<<endl;
        }
    }
    return 0;
}

B. Dubious Cyrpto

https://codeforces.com/contest/1379/problem/B

题意:

给出三个数字\(l,r,m\),要求找出\(a,b,c\)满足:\(l\le a,b,c\le r, na+b-c=m\),且要保证n为正数。
变形一下:\(\left( m+c-b \right) \%a=0\),想了一会有没有特解然后发现数据量不大,那就枚举\(a\)然后判断\(b-c\)是否满足,有个小坑是如果\(m/a=0\)有一种情况就不能考虑了,但是另外一只却可以(which makes me wa once T_T)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=2e5+1000;
ll t,n,m,l,r;
int main(){
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>t;
    while(t--){
        cin>>l>>r>>m;
        ll a,b,c;
        for(a=l;a<=r;a++){
            ll mo=m%a;
            if(mo==0){
                b=l,c=l;
                break;
            }else{
                if(-mo>=-(r-l)&&m/a!=0){
                    c=l,b=c+mo;
                    break;
                }else{
                    mo=a-mo;
                    if(mo<=r-l){
                        b=l,c=b+mo;
                        break;
                    }                    
                }
            }
        }
        cout<<a<<' '<<b<<' '<<c<<endl;
    }
    return 0;
}
posted @ 2020-07-31 17:33  Zabreture  阅读(62)  评论(0编辑  收藏  举报