《Codeforces Round #732 (Div. 1)》
题目一题比一题难读.....
A:签到了属于是。
考虑每个点操作偶数次才能保证方向不变。
那么对于它排序后的位置一定要保证距离为偶数距离才行。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e5 + 5; const int M = 5e5 + 5; const LL Mod = 1e9 + 7; #define pi acos(-1) #define INF 1e9 #define dbg(ax) cout << "now this num is " << ax << endl; int a[N],ji[N],ou[N]; void solve() { int n;scanf("%d",&n); memset(ji,0,sizeof(ji)); memset(ou,0,sizeof(ou)); for(int i = 1;i <= n;++i) { int x;scanf("%d",&x); a[i] = x; if(i % 2 == 0) ou[x]++; else ji[x]++; } sort(a + 1,a + n + 1); for(int i = 1;i <= n;++i) { if(i % 2 == 0) { if(ou[a[i]] != 0) ou[a[i]]--; else { printf("NO\n"); return ; } } else { if(ji[a[i]] != 0) ji[a[i]]--; else { printf("NO\n"); return ; } } } printf("YES\n"); } int main() { int ca;scanf("%d",&ca); while(ca--) { solve(); } //system("pause"); return 0; }
B:感觉到是组合数学不过挺抽象的感觉。
模拟操作了几次可以发现,两个连续的1可以不断平移,单个的1就无法移动。
那么题目就可以看成了求连续的11和0的排列。即C(cnt11 + cnt0,cnt11).
这里当11和0的排列固定后,单个1的位置也就固定了。
可能会疑惑1的位置为什么也固定了。
看这个例子.
110111
如果排列为11011.
单个1插入中间变成111011 -- 发现从原始的无法实现
单个1插入右边变成110111 -- 唯一的方案。
其他的位置插入可以发现都无法实现。所以对于11和0固定后的状态,1的状态也就只有1种固定的位置。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e5 + 5; const int M = 1e3 + 5; const double eps = 1e-10; const LL Mod = 998244353; #define pi acos(-1) #define INF 1e9 #define dbg(ax) cout << "now this num is " << ax << endl; LL f[N]; void init() { f[0] = 1; for(int i = 1;i < N;++i) f[i] = f[i - 1] * i % Mod; } LL quick_mi(LL a,LL b) { LL re = 1; while(b) { if(b & 1) re = re * a % Mod; b >>= 1; a = a * a % Mod; } return re; } LL C(LL n,LL m) { return f[n] * quick_mi(f[m],Mod - 2) % Mod * quick_mi(f[n - m],Mod - 2) % Mod; } void solve() { int n;scanf("%d",&n); string s;cin >> s; int cnt1 = 0,cnt2 = 0; for(int i = 0;i < s.size();++i) { if(s[i] == '1' && i < s.size() - 1 && s[i + 1] == '1') cnt1++,i++; else if(s[i] == '0') cnt2++; } LL ans = C(cnt1 + cnt2,cnt1); printf("%lld\n",ans); } int main() { init(); int ca;scanf("%d",&ca); while(ca--) { solve(); } // system("pause"); return 0; }