Remove Smallest
注意到数据范围很小( 1 ≤ a i ≤ 100 1≤ai≤100 1≤ai≤100),求得输入的数组中的最小值和最大值,从最小到最大走一遍,看是不是其中的每个值都有,若无则NO,全有则YES
#include
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f3f
// #define TDS_ACM_LOCAL
int n, mi, mx, vis[109], a;
void solve(){
cin>>n;
mx=0, mi=INF;
memset(vis, 0, sizeof(vis));
for(int i=1; i<=n; i++){
cin>>a;
vis[a]=1;
if(a>mx) mx=a;
if(a<mi) mi=a;
}
int flag=0;
for(int i=mi; i<=mx; i++){
if(vis[i]==0) {flag=1; break;}
}
if(flag) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
return ;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
int T;
cin>>T;
while(T--) solve();
return 0;
}
Gifts Fixing
很明显的a和b数组最终变成的值为各自数组中的最小值,所以对于对于每个位置的变化次数很容易就可以得到,对于a和b的变换可以是a–也可以是b–,或者同时两个自减,所以a和b相应位置的操作次数即为两个分别操作次数中最大的那个,然后对所有的操作次数求和即为最小操作次数
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f3f
// #define TDS_ACM_LOCAL
const int N=59;
int n, a[N], b[N];
int mia, mib;
long long ans;
void solve(){
cin>>n;
ans=0;
mia=mib=INF;
for(int i=1; i<=n; i++){
cin>>a[i];
if(a[i]<mia) mia=a[i];
}
for(int i=1; i<=n; i++){
cin>>b[i];
if(b[i]<mib) mib=b[i];
}
for(int i=1; i<=n; i++){
ans+=max(a[i]-mia, b[i]-mib);
}
cout<<ans<<endl;
return ;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
int T;
cin>>T;
while(T--) solve();
return 0;
}
Boats Competition
给你一个长度为n的数组,从中两两取值,相加的值必须相等,求取得的值对最多的对数
注意到数据范围很小 1 ≤ n ≤ 50 1≤n≤50 1≤n≤50,所以我们可以直接枚举 S S S的取值,从2到 2 ∗ n 2*n 2∗n,然后对于每个取值分别计算其中可以去到的对数的个数,求得最大值即可
#include
#include
#include
using namespace std;
// #define TDS_ACM_LOCAL
const int N=110;
int n, x, a[N], ans, cnt;
void solve(){
cin>>n;
memset(a, 0, sizeof(a));
for(int i=0; i<n; i++) cin>>x, a[x]++;
ans=0;
for(int i=2; i<=2*n; i++){
cnt=0;
for(int j=1; j<=i; j++) if(a[i-j]) cnt+=min(a[j], a[i-j]);
ans=max(ans, cnt/2); //除2是因为会取到两次
}
cout<<ans<<endl;
return ;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
int T;
cin>>T;
while(T--) solve();
return 0;
}
Binary String To Subsequences
给你一个长度为n的包含0和1的字符串,请你求出其中最少的01子字符串(0和1交替出现)的个数并且求出每个位置的0和1应该是第几个子字符串的
可以分别用两个队列分别存以0结尾和以1结尾的子字符串,代码中用idx表示的子字符串个数
1、将1接到0结尾的子字符串后变成1,存到1的队列
2、将0接到1结尾的子字符串后变成0,存到0的队列
3、如果没有以0结尾的子字符串,就创建一个新的
4、如果没有以1结尾的子字符串,就创建一个新的
#include
#include
#include
#include
using namespace std;
// #define TDS_ACM_LOCAL
const int N=2e5 +9;
int n, x, a[N], idx;
string s;
void solve(){
cin>>n;
cin>>s;
idx=0;
queue<int> q0, q1;
for(int i=0; i<n; i++){ //idx表示的子字符串的个数,所以idx++代表创建了一个新的子字符串
if(s[i]=='0'){
if(!q1.empty()){ //将0接到1结尾的子字符串后变成0,存到0的队列
x=q1.front(); q1.pop();
a[i]=x;
q0.push(x);
}
else{ //如果没有以1结尾的子字符串,就创建一个新的
a[i]=++idx;
q0.push(idx);
}
}
else{
if(!q0.empty()){ //将1接到0结尾的子字符串后变成1,存到1的队列
x=q0.front(); q0.pop();
a[i]=x;
q1.push(x);
}
else{ //如果没有以0结尾的子字符串,就创建一个新的
a[i]=++idx;
q1.push(idx);
}
}
}
cout<<idx<<endl;
for(int i=0; i<n; i++) cout<<a[i]<<" ";
cout<<endl;
return ;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
#ifdef TDS_ACM_LOCAL
freopen("D:\\VS code\\.vscode\\testall\\in.txt", "r", stdin);
freopen("D:\\VS code\\.vscode\\testall\\out.txt", "w", stdout);
#endif
int T;
cin>>T;
while(T--) solve();
return 0;
}