CCPC2018-湖南全国邀请赛-重现赛(填坑中)

String Transformation HDU - 6282 

题意:

说有两个字符串S,T,以及规则:可以通过插入或删除子字符串"aa","bb"和"abab"来转换字符串,即对于字符串 A∘ ∘ v ,A 可以变换为 A = u  v,反过来也可以。问最后能否将 S 变换为 T 

题解:

由于没有字符C的替换规则,所以可以确定C的数量不相等的话一定不能够使得S==T,再者,如果任意两个C之间,以及C和边界之间 a 的数量以及b的数量不同时为奇偶的时候也不能使得S=T,√

#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <string>
#include <set>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <iomanip>
#pragma GCC optimize(2)
using namespace std;
const int inf=0x3f3f3f3f;
#define ll long long
const int mod = 1e9+7;/// 998244353;
const int mxn = 8e4 +7;
const int N = 8e4 + 7 ;
ll _ , n , m , t , k , ans , cnt ;
template <class T>
void rd(T &x){
    T flag = 1 ; x = 0 ; char ch ;
    ch = getchar();
    while(!isdigit(ch)) { if(ch=='-') flag = -1; ch = getchar(); }
    while(isdigit(ch)) { x = (x<<1) + (x<<3) + (x^48); ch = getchar(); }
    x*=flag;
}
void solve()
{
    string s1 ,s2 ;
    while(cin>>s1>>s2){
        int n1 = count(s1.begin(),s1.end(),'c');
        int n2 = count(s2.begin(),s2.end(),'c');
        if(n1!=n2){
            cout<<"No"<<endl;
            continue;
        }
        int i = 0 , j = 0 , flag = 1 ;
        while(i<=s1.size() && j<=s2.size()){
            int la1 = 0 , lb1 = 0 ,  la2 = 0 , lb2 = 0 ;
            while(s1[i]!='c'&& i<s1.size()) {
                if(s1[i]=='a') la1++;
                else lb1++;
                i++;
            }
            while(s2[j]!='c' && j<s2.size()){
                if(s2[j]=='a') la2++;
                else lb2++;
                j++;
            }
            i++ , j++ ;
            if(la1%2!=la2%2 || lb1%2!=lb2%2){
                cout<<"No"<<endl;
                flag = 0 ;
                break;
            }
        }
        if(flag) cout<<"Yes"<<endl;
    }
}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0) ; cout.tie(0);
    solve();
}
View Code
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <string>
#include <set>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <iomanip>
#pragma GCC optimize(2)
using namespace std;
const int inf=0x3f3f3f3f;
#define ll long long
const int mod = 1e9+7;/// 998244353;
const int mxn = 8e4 +7;
const int N = 8e4 + 7 ;
ll _ , n , m , t , k , ans , cnt ;
template <class T>
void rd(T &x){
    T flag = 1 ; x = 0 ; char ch ;
    ch = getchar();
    while(!isdigit(ch)) { if(ch=='-') flag = -1; ch = getchar(); }
    while(isdigit(ch)) { x = (x<<1) + (x<<3) + (x^48); ch = getchar(); }
    x*=flag;
}
vector<int> calc(string s1)
{
    vector<int> v;
    int ans = 0 ;
    for(int i=0;i<=s1.size();i++)
        if(i==s1.size() || s1[i]=='c')
            v.push_back(ans) , ans = 0 ;
        else ans^=s1[i];
    return v;
}
void solve()
{
    string s1 ,s2 ;
    while(cin>>s1>>s2){
        if(calc(s1) == calc(s2)) cout<<"Yes
";
        else cout<<"No
";
    }
}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0) ; cout.tie(0);
    solve();
}
位运算

2018 HDU - 6286 

题意:

计算两个给定区间数的乘积是2018的倍数的个数

题解:

可以发现,2018的因子有1 ,2 , 1009 , 2018 ,那么我们可以将区间划分为 (1)是2的倍数但不是2018的倍数,(2)是奇数但不是1009的倍数

那么,最后是2018的倍数的组合有 左区间*右区间2018的倍数的个数 + 右区间*左区间2018的倍数的个数 + 左区间(1)*右区间(2) + 右区间(2)*左区间(1) - 

#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <string>
#include <set>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <iomanip>
#pragma GCC optimize(2)
using namespace std;
const int inf=0x3f3f3f3f;
#define ll long long
const int mod = 1e9+7;/// 998244353;
const int mxn = 8e4 +7;
const int N = 8e4 + 7 ;
ll _ , n , m , t , k , ans , cnt ;
template <class T>
void rd(T &x){
    T flag = 1 ; x = 0 ; char ch ;
    ch = getchar();
    while(!isdigit(ch)) { if(ch=='-') flag = -1; ch = getchar(); }
    while(isdigit(ch)) { x = (x<<1) + (x<<3) + (x^48); ch = getchar(); }
    x*=flag;
}
void solve()
{
    ll l,r,L,R;
    while(cin>>l>>r>>L>>R){
        ll l2018 = r/2018 - (l-1)/2018 ;
        ll l1009 = r/1009 - (l-1)/1009 - l2018;
        ll l2 = r/2 - (l-1)/2 - l2018 ;

        ll L2018 = R/2018 - (L-1)/2018 ;
        ll L1009 = R/1009 - (L-1)/1009 - L2018 ;
        ll L2 = R/2 - (L-1)/2 - L2018 ;
        cout<<(r-l+1)*L2018 + (R-L+1)*l2018 + l2*L1009 + L2*l1009 - l2018*L2018 <<endl;
    }
}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0) ; cout.tie(0);
    solve();
}
View Code

Vertex Cover 

题意:

有一个N个点的完全图,编号范围是【0,N-1】,第 i 个点的权值为 2i ,先手选择完全图的一些边集,记为E,后手选择构成边集E的一些点集V,保证选择的边集中的每条边的一端或者两端存在于V中,问选取的边集的方案数有多少

题解:

由于选取的点的权值和是以二进制的形式给出的,也就是说,二进制串中‘1’的位置P对应的点就是被选中的点,对于选取的点来说,选择比P更大的位置的点,从而可以降低权值。(

#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <string>
#include <set>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <iomanip>
#pragma GCC optimize(2)
using namespace std;
const int inf=0x3f3f3f3f;
#define ll long long
#define ull unsigned long long
const int mod = 1e9+7;/// 998244353;
const int mxn = 1e5 +7;
const int N = 8e4 + 7 ;
int _ , n , m , t , k , ans , cnt , si ;
template <class T>
void rd(T &x){
    T flag = 1 ; x = 0 ; char ch = getchar() ;
    while(!isdigit(ch)) { if(ch=='-') flag = -1; ch = getchar(); }
    while(isdigit(ch)) { x = (x<<1) + (x<<3) + (ch^48); ch = getchar(); }
    x*=flag;
}
ll fac[mxn] ;
void solve()
{
    fac[0] = 1 ;
    for(int i=1;i<=mxn;i++) fac[i] = fac[i-1]*2 % mod ;
    string str;
    while(cin>>n>>str){
        ll ans = 1 , now = n - str.size() ;
        for(int i=0;i<str.size();i++)
            if(str[i]=='1')
                ans = ans*(fac[now] - 1 + mod) % mod * fac[str.size()-i-1] % mod ;
            else 
                now++;
        cout<<ans<<endl;
    }
}
int main()
{
    ios::sync_with_stdio(false); cin.tie(0) ; cout.tie(0);
    solve();
}
View Code
所遇皆星河
原文地址:https://www.cnblogs.com/Shallow-dream/p/13648411.html