1. 程式人生 > 實用技巧 >Codeforces Round #658 (Div. 2)(ABC,B為博弈)

Codeforces Round #658 (Div. 2)(ABC,B為博弈)

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

題意:

找出最短陣列c[],保證它同時是a[]和b[]的子序列

解析:

如果a[]和b[]存在相同數字,直接輸出它

否則不存在

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int MAX = 2e6+100;
const int mod = 998244353;
const double PI = 3.141592654;

map <int , int > mm;
int main (void
) { int T; cin>>T; while(T--) { int x,y; cin>>x>>y; mm.clear(); for(int i=0; i<x; i++) { int t; cin>>t; mm[t] = 1; } int cnt = 0; int flag = 0;
for(int i=0; i<y; i++) { int t; cin>>t; if(mm[t] != 0) { flag = 1; cnt = t; } } if(flag == 1) { cout<<"YES"<<endl; cout<<1<<"
"<<cnt<<endl; } if(flag == 0) cout<<"NO"<<endl; } return 0; }

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

題意:

每堆石頭數:a1~an

操作:

兩人依次從最左邊非0堆拿取任意石子

不能操作的人輸掉

解析:

假設所有堆的石子數都>1,那麼先手可以對結果進行任意的操控(具體他怎麼拿才能贏不需要管),通過對某個堆取完還是取到1進行結果的操控。

如果存在石子數==1的情況,

假設:1,1,1......1,a,b,c..... a>1

前面的1中,每次操作只能取1,所以先手和後手依次取。輪到誰拿a,誰就贏了,原理同上,只要某個堆>1,就可以對結果進行任意操控。

#include<iostream>
#include<cstring>
#include<string.h>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
ll a[maxn];
int b[maxn];
int qk(ll a, ll b,ll c)
{
    ll ans=1;
    a=a%c;
    while(b)
    {
        if(b%2==1)
            ans=(ans*a)%c;
        b=b/2;
        a=(a*a)%c;
    }
    return  ans;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,x;
        int cnt1=0,cnt2=0;
        cin>>n;
        int k;
        int ok1=0;
        int ok2=0;
        for(int i=1;i<=n;i++)
        {
            cin>>x;
            if(x==1)
            {
                ok1=1;
            }
            if(x!=1&&!ok2)
            {
                k=i;
                ok2=1;
            }
        }
        if(!ok2)  //全1
        {
            if(n%2!=0)
                cout<<"First"<<endl;
            else
                cout<<"Second"<<endl;continue;
        }
        if(!ok1)  //全>1
        {
            cout<<"First"<<endl;continue;
        }
        if(k%2!=0)
            cout<<"First"<<endl;
        else
            cout<<"Second"<<endl;
    }
}

C1:http://codeforces.com/contest/1382/problem/C1

題意:

01串s1,s2

操作s1:

每次找到x,前x進行0/1互換,然後倒置。

求s1==s2的運算元和過程(任意符合的結果)

解析:

k<=3n,從這裡入手,每個字元操作3次

對於s1[x]!=s2[x]

先將前x進行0/1互換,倒置,再對s1[1]進行0/1互換,再對前x操作,可以使得s1[x]==s2[x]而且不影響之前的匹配。

#include<iostream>
#include<cstring>
#include<string.h>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
const int maxn=1e3+10;
const int mod=1e9+7;
char s1[maxn],s2[maxn];
ll a[maxn];
int b[maxn];
int qk(ll a, ll b,ll c)
{
    ll ans=1;
    a=a%c;
    while(b)
    {
        if(b%2==1)
            ans=(ans*a)%c;
        b=b/2;
        a=(a*a)%c;
    }
    return  ans;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
    //    string s1,s2;
        int n;
        cin>>n;
        int tot=0;
        scanf("%s",s1+1);
        scanf("%s",s2+1);
        for(int i=1;i<=n;i++)
        {
            if(s1[i]!=s2[i])
            {
                b[tot++]=i;
                b[tot++]=1;
                b[tot++]=i;
            }
        }
        cout<<tot<<" ";
        for(int i=0;i<tot;i++)
            cout<<b[i]<<" ";
            cout<<endl;
    }
}