A题:AquaMoon and Two Arrays
题意:给定n和数组an,bn。操作为选择两个下标使得ai–,aj++,使an和bn数组相同。
数据范围:多组输入t<100,n<100,ai,bi<100
样例解释:
输入:
4
4
1 2 3 4
3 1 2 4
2
1 3
2 1
1
0
0
5
4 3 2 1 0
0 1 2 3 4
输出:
2
2 1
3 1
-1
0
6
1 4
1 4
1 5
1 5
2 5
2 5
第一组:
i=2, j=1: [1,2,3,4]→[2,1,3,4];
i=3, j=1: [2,1,3,4]→[3,1,2,4];
思路:数据范围小,直接模拟遍历,查找符合的下标记录并修改。
分类:暴力
通过代码:
#include<bits/stdc++.h>
using namespace std;
int a[105],b[105];
int main() {
int t;
cin>>t;
while(t--) {
int n;
cin>>n;
vector<pair<int,int> >v;//存入需要交换的i,j
for(int i=1; i<=n; i++)cin>>a[i];
for(int i=1; i<=n; i++)cin>>b[i];
for(int i=1; i<=n-1; i++) {//暴力遍历n2
for(int j=i+1; j<=n; j++) {
if(a[i]>b[i]&&a[j]<b[j]) {//如果i位大并且j位小
a[i]--;//修改a[i],a[j]值
a[j]++;
v.push_back({i,j});//存入i,j
j--;//注意回退
} else if(a[i]<b[i]&&a[j]>b[j]) {//如果i位小并且j位大同理
a[i]++;
a[j]--;
v.push_back({j,i});
j--;
}
}
}
int flag=1;
for(int i=1;i<=n;i++)if(a[i]!=b[i])flag=0;//判断最后是否相同
if(flag) {
cout<<v.size()<<endl;
for(auto x:v)cout<<x.first<<" "<<x.second<<endl;
} else {
cout<<-1<<endl;
}
}
return 0;
}
B题:AquaMoon and Stolen String
题意:给定字符串数量n和长度m,给定n行和n-1行,通过n行中每一位的任意交换,形成和另外n-1行相同的字符串,输出剩下的字符串
数据范围:多组输入t<100,n,m<1e5
数据范围:多组输入t<1e4,|s|<26
样例解释:
输入:
3
3 5
aaaaa
bbbbb
ccccc
aaaaa
bbbbb
3 4
aaaa
bbbb
cccc
aabb
bbaa
5 6
abcdef
uuuuuu
kekeke
ekekek
xyzklm
xbcklf
eueueu
ayzdem
ukukuk
输出:
ccccc
cccc
kekeke
第一组:显然剩余了第三行
思路:统计每一位的字符串个数,将n行和n-1行相减,剩下的字符为当前位剩余字符。
分类:计数
通过代码:
#include<bits/stdc++.h>
using namespace std;
string s1[100005],s2[100005];
int cnt[200];
int main() {
int t;
cin>>t;
while(t--) {
int n,m;
vector<char>v;
cin>>n>>m;
for(int i=0; i<n; i++) cin >> s1[i];
for(int i=0; i<n-1; i++) cin >> s2[i];
for(int i=0; i<m; i++) {//每一位
memset(cnt,0,sizeof cnt);
for(int j=0; j<n; j++)cnt[s1[j][i]]++;//统计增加的字符
for(int j=0; j<n-1; j++)cnt[s2[j][i]]--;//统计减少的字符
for(int j='a'; j<='z'; j++) {
if(cnt[j]==1)v.push_back(j);//差值为1的为剩余字符
}
}
for(auto x:v)cout<<(char)x;
cout<<endl;
}
return 0;
}
C题:AquaMoon and Strange Sort
题意:给定n和数组an,初始所有元素朝右,与相邻元素交换后改变方向,求最终能否升序且方向均朝右。
数据范围:多组输入t<50,n<1e5,ai<1e5
样例解释:
输入:
3
4
4 3 2 5
4
3 3 2 2
5
1 2 3 5 4
输出:
YES
YES
NO
第一组:
交换1和2. [3,4,2,5]. 方向: 左左右右
交换2和3. [3,2,4,5]. 方向: 左左右右
交换1和2. [2,3,4,5]. 方向: 右右右右
思路:如果要使每个元素最终都朝右,说明交换次数%2=0,即奇数位和奇数位交换,偶数位和偶数位交换,同时又要满足升序条件。只需要把奇数位和偶数位独立排序一次,再将原数组排序一次,即可判断答案
分类:奇偶+排序
通过代码:
#include<bits/stdc++.h>
using namespace std;
int main() {
int t;
cin>>t;
while(t--) {
int n,x;
cin>>n;
vector<int>a,b,c;
for(int i=0; i<n; i++) {
cin>>x;
a.push_back(x);
}
for(int i=0; i<n; i++) {
if(i%2==1)b.push_back(a[i]);
else c.push_back(a[i]);
}
sort(a.begin(),a.end());
sort(b.begin(),b.end());
sort(c.begin(),c.end());
int flag=1;
for(int i=0; i<n; i++) {
if(i%2==1) {
if(a[i]!=b[i/2])flag=0;
} else {
if(a[i]!=c[i/2])flag=0;
}
}
if(flag)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
D题:AquaMoon and Chess
题意:给定字符串长度n和一个01字符串,可以完成操作:
如果s[i]==1&&s[i+1]==1&&s[i+2]==0则s[i]=0,s[i+2]=1;
如果s[i]==1&&s[i-1]==1&&s[i-2]==0则s[i]=0,s[i-2]=1;
请问最终有多少种不同结果,模998244353
数据范围:多组输入t<1e4,n<1e5
样例:
样例输入:
6
4
0110
6
011011
5
01010
20
10001111110110111000
20
00110110100110111101
20
11101111011000100010
样例输出:
3
6
1
1287
1287
715
思路:打表找规律。如果只有0,显然不会变化;如果只有孤立的1,显然也不会有变化;如果有两个连续的1,可以跑遍整个数组;
如果此时出现孤立的1,遇到时会被传递,不具有贡献;如果有三个连续的1,仅能看成(1+1)*两个连续的1,无法造成额外的贡献;
如果有四个连续的1,可以看作(1+1+1)*两个连续的1……简化了连续1问题以后,发现状态数和这个11所放的位置有关。
所有的11都可以放到0的位置上,即变成了有个数(0)和个数(11)之和个位置,来放置个数(11),求多少个方案数。
即组合数问题。
分类:思维,排列组合
通过代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mod=998244353;
ll qmi(ll a, ll k)//快速幂模板
{
int res = 1;
while (k)
{
if (k & 1) res = (ll)res * a % mod;
a = (ll)a * a % mod;
k >>= 1;
}
return res;
}
ll C(ll a, ll b)//通过定理求组合数C(a, b)
{
ll res = 1;
for (int i = 1, j = a; i <= b; i ++, j -- )
{
res = (ll)res * j % mod;
res = (ll)res * qmi(i, mod - 2) % mod;
}
return res;
}
ll lucas(ll a, ll b)
{
if (a < mod && b < mod) return C(a, b);
return (ll)C(a % mod, b % mod)*lucas(a / mod, b / mod) % mod;
}
int main() {
ll t;
cin>>t;
while(t--) {
ll n;
string s;
cin>>n>>s;
ll cnt0=0,cnt1=0;
for(int i=0; i<s.size(); i++) {
if(s[i]=='0')cnt0++;//统计0的个数
}
for(int i=0; i<s.size(); i++) {
if(s[i]=='1') {
int pos=i;
while(s[pos]=='1'){
pos++;
}
cnt1+=(pos-i)/2;//统计多少个连续的11个数
i=pos;
}
}
cout<<lucas(cnt0+cnt1,cnt1)<<endl;//组合数问题
}
return 0;
}
E题:AquaMoon and Permutations
分类:???
F题:AquaMoon and Wrong Coordinate
分类:???