文章目录
A. Problem Generator
题意:
弗拉德计划在下个月举行 m m m 轮比赛。每轮比赛应包含一个难度为"A"、“B”、“C”、“D”、“E”、"F "和 "G "的问题。弗拉德已经有了一个 n问题库,其中 i /th问题的难度为 ai 。这些问题可能不够多,所以他可能需要再想出一些问题。弗拉德想要尽可能少地提出问题,所以他要求你找出他需要提出的问题的最小数量,以便举行 m轮比赛。
题解:
用map记录每个字母出现的次数,然后判断需要添加几个够m个,求和就是答案。
代码:
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
void solve(){
int n,m;
map<char,int> mp;
cin>>n>>m;
string s;
cin>>s;
for(int i=0;i<(int)s.size();i++) mp[s[i]]++;
int ans=0;
for(int i=0;i<7;i++){
char temp=char(i+'A');
int x=(m-mp[temp]);
if(x<0) continue;
ans+=x;
}
cout<<ans<<endl;
}
int main(){
int t;
cin>>t;
while(t--) solve();
return 0;
}
B. Choosing Cubes
题意:
有n个元素数组 a a a,德米特喜欢第f个元素,然后数组会进行从大到小排序,然后将前k个元素删除,若德米特最爱的元素在所有情况下都会被移除,则输出 y e s yes yes;如果在任何情况下都不会被移除,则输出 n o no no;如果可能会被移除或留下,则输出 M A Y B E MAYBE MAYBE。
题解:
记录排序前第f个元素的值,以及数组中每个值的元素共有多少个,然后将数组排序,将前k个元素出现次数减去,观察f的出现次数如何变化,若不变则输出 n o no no,若变为0,则输出 y e s yes yes,若减少但不为0.则输出 M A Y B E MAYBE MAYBE。
代码:
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
const int N=110;
int a[N],b[N];
void solve(){
int n,f,k;
map<int,int> mp;
cin>>n>>f>>k;
for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i],mp[a[i]]++;
int temp=a[f];
int x=mp[temp];
sort(a+1,a+1+n, greater<int>());
for(int i=1;i<=k;i++){
mp[a[i]]--;
}
int y=mp[temp];
if(y==0) cout<<"YES"<<endl;
else if(y<x&&y>0) cout<<"mAyBe"<<endl;
else if(x==y) cout<<"No"<<endl;
}
int main(){
int t;
cin>>t;
while(t--) solve();
return 0;
}
C. Sofia and the Lost Operations
题意:
有一个由 n n n 个整数 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,…,an 组成的数组。对它进行 m m m 修改操作。
每个修改操作都由一对数字
⟨
c
j
,
d
j
⟩
\langle c_j, d_j \rangle
⟨cj,dj⟩ 来描述,这意味着数组中索引为
c
j
c_j
cj 的元素应该被赋值
d
j
d_j
dj ,即执行赋值
a
c
j
=
d
j
a_{c_j} = d_j
acj=dj 。
你发现了一个由
n
n
n 个整数
b
1
,
b
2
,
…
,
b
n
b_1, b_2, \ldots, b_n
b1,b2,…,bn 组成的数组。你想知道这个数组是否是m次操作后的数组。你知道原始数组的值以及
d
1
,
d
2
,
…
,
d
m
d_1, d_2, \ldots, d_m
d1,d2,…,dm 的值。结果发现数值
c
1
,
c
2
,
…
,
c
m
c_1, c_2, \ldots, c_m
c1,c2,…,cm 丢失了。
问是否存在一个序列
c
1
,
c
2
,
…
,
c
m
c_1, c_2, \ldots, c_m
c1,c2,…,cm 使得对数组
a
1
,
a
2
,
…
,
a
n
a_1, a_2, \ldots, a_n
a1,a2,…,an 的修改操作
⟨
c
1
,
d
1
,
⟩
,
⟨
c
2
,
d
2
,
⟩
,
…
,
⟨
c
m
,
d
m
⟩
\langle c_1, d_1, \rangle, \langle c_2, d_2, \rangle, \ldots, \langle c_m, d_m \rangle
⟨c1,d1,⟩,⟨c2,d2,⟩,…,⟨cm,dm⟩ 的连续应用将其转换为数组
b
1
,
b
2
,
…
,
b
n
b_1, b_2, \ldots, b_n
b1,b2,…,bn ?
题解:
只有当 a i a_{i} ai!= b i b_{i} bi时,都存在一个 d j d_{j} dj= b i b_{i} bi,且d数组的最后一个数组和b数组的其中一个元素相同时,才满足可以转换,否则不可以。
代码:
#include<iostream>
#include<algorithm>
#include<map>
#define int long long
using namespace std;
const int N=2e5+10;
int a[N],b[N],d[N];
void solve(){
int n;
map<int,int> mp;
map<int,int> temp;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i],temp[b[i]]++;
int m;
cin>>m;
for(int i=1;i<=m;i++) cin>>d[i],mp[d[i]]++;
int flag=1;
for(int i=1;i<=n;i++){
if(a[i]!=b[i]) flag=0;
}
if(flag){
if(temp[d[m]]) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return;
}
for(int i=1;i<=n;i++){
if(a[i]!=b[i]){
mp[b[i]]--;
if(mp[b[i]]<0){
cout<<"NO"<<endl;
return;
}
}
}
if(temp[d[m]]==0){
cout<<"NO"<<endl;
return;
}
cout<<"Yes"<<endl;
}
signed main(){
int t;
cin>>t;
while(t--) solve();
return 0;
}
D. GCD-sequence
题意:
给定一个含有 n n n个元素的数组,每两个相邻的元素求一个 g c d gcd gcd,将每次求得 g c d gcd gcd构成一个数组 b b b,问b是否是一个不递减的数组,若不是是否可以在 a a a中删除一个元素,重新求得 b b b为不递减。
题解:
先遍历数组 a a a,求出数组 b b b,然后针对递减的点 i i i,分别尝试删除 a i − 1 a_{i-1} ai−1, a i a_{i} ai, a i + 1 a_{i+1} ai+1,看着三种删除方法是否可以使得b不递减。
代码:
#include<iostream>
#include<algorithm>
#include<math.h>
#define int long long
using namespace std;
const int N=2e5+10;
int a[N],b[N],c[N];
int n;
bool check(int idx) {
copy(a + 1, a + idx, c + 1);
copy(a + idx + 1, a + n + 1, c + idx);
int m = n - 1;
for (int i = 1; i < m; ++i) b[i] = __gcd(c[i], c[i + 1]);
for (int i = 2; i < m; ++i) {
if (b[i - 1] > b[i]) return false;
}
return true;
}
bool solve(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<n;i++) b[i]=__gcd(a[i+1],a[i]);
for(int i=2;i<n;i++)
if(b[i-1]>b[i]) return check(i-1)||check(i)||check(i+1);
return true;
}
signed main(){
int t;
cin>>t;
while(t--){
if(solve()) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}
E. Permutation of Rows and Columns
题意:
给出两个n*m的矩阵 a a a, b b b,每次操作可以选取两行或者两列进行交换,问是否可以对矩阵 a a a进行有限次操作将 a a a变成矩阵 b b b。
题解:
交换两行操作只会影响到重排行的位置,原来在同一行的元素也还在同一行,在同一列的也是如此。交换两列操作也是这样,所以只需要判断对于 a a a矩阵的每一行 b b b矩阵中是否存在与其元素相同的行, a a a矩阵的每一列 b b b矩阵中是否存在与其元素相同的列。
代码:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long int
bool cmp(vector<int>& x,vector<int>& y)
{
return x[0]<y[0];
}
bool f(vector<vector<int>> a,vector<vector<int>> b,int n,int m)
{
for(int i=0;i<n;i++)
{
sort(a[i].begin(),a[i].end());
sort(b[i].begin(),b[i].end());
}
sort(a.begin(),a.end(),cmp);
sort(b.begin(),b.end(),cmp);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(a[i][j]!=b[i][j])
return true;
}
}
return false;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
vector<vector<int>> a(n,vector<int>(m)),b(n,vector<int>(m));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
cin>>a[i][j];
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
cin>>b[i][j];
}
vector<vector<int>> ta(m,vector<int>(n)),tb(m,vector<int>(n));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
ta[j][i]=a[i][j];
tb[j][i]=b[i][j];
}
}
if(f(a,b,n,m)||f(ta,tb,m,n))
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
}