CCPC2018-湖南全国邀请赛-重现赛(填坑中)
String Transformation HDU - 6282
题意:
说有两个字符串S,T,以及规则:可以通过插入或删除子字符串"aa","bb"和"abab"来转换字符串,即对于字符串 A= u ∘ w ∘ 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(); }
#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\n"; else cout<<"No\n"; } } 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(); }
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(); }
所遇皆星河