A
大意:给你一串任意的序列,可以通过任意改变他们的位置,问最后能否严格单调递增。
思路:sort一遍,检查是否有相等的项
AC代码:
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
void solve(){
int n;
cin >> n;
vector<int> a(n + 1);
for(int i = 1; i <= n; i ++) cin>> a[i];
sort(a.begin() + 1 ,a.end());
for(int i = 1; i < n; i++){
if(a[i] == a[i + 1]){
cout << "no\n";
return;
}
}
cout << "yes\n";
}
int main(){
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t;
cin >> t;
while(t--) solve();
return 0;
}
B
题目大意:
原字符串a
变化后的字符串b
叫你 找回原来的字符串a
变化的要求:将a串 两两拉开,得到b串
ac代码:
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
void solve(){
string b;
cin >> b;
string a;
for(int i = 0 ; i < b.size(); i ++){ //遍历b串,求a串
if(i == 0 || i == b.size() - 1) {
a += b[i];
}else{
a += b[i];
i++;
}
}
cout << a << endl;
}
int main(){
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t;
cin >> t;
while( t--) solve();
return 0;
}
C
大意:
给你一串数字序列a
询问是否可以变成字符串序列
变换规则:相同的数字,必须变成相同的字母。变成哪个字母是任意。
思路:检查所有相等的数字,对应变成的字母必须相等。否则就是no
AC代码:
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
void solve(){
int n;
cin >> n;//输入n
vector<int> a(n + 1);
for(int i = 0; i < n ;i ++) cin >> a[i]; //读取第一行数字序列
string b; //读取string
cin >> b;
for(int i = 0; i < n; i ++ ){
for(int j = i; j < n; j ++){
if(a[i] == a[j] && b[i] != b[j]) { //当前数字和后面的数字相等,必须变成同一个字母
cout << "no\n";
return;
}
}
}
cout << "yes\n";
}
int main(){
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t;
cin >> t;
while(t--) solve();
return 0;
}
D
题目大意:
求2个下标和最大。 要求这两个下标对应的值必须互质。
思路:去掉重复元素,拿到最大下标。O方暴力找质数,维护一个最大下标和ans
AC代码:
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
bool tag[1000 + 5];
int sp_max[1000 + 5];
int gcd(int a, int b){
if(b) return gcd(b, a % b);
return a;
}
void solve(){
int n;
cin >> n;
memset(tag, 0, sizeof tag);
memset(sp_max, 0, sizeof sp_max);
vector<int> a(n + 1);
for(int i = 1;i <= n; i ++) cin >> a[i];//输入数据
//去掉重复元素,保留下标最大值
for(int i = 1; i <= n ;i ++){
tag[a[i]] = true;
sp_max[a[i]] = i;
}
vector<int> b; //将出现过的值,添加到数组里
for(int i = 1; i <= 1000; i ++){
if(tag[i]) b.push_back(i);
}
int ans = -1;
// 暴力搜索,这1000个数据
for(int i = b.size() - 1; i >= 0; i --){
for(int j = b.size() - 1; j >= 0; j --){
//判断,i j 对应的元素,互质
if(gcd(b[i], b[j]) == 1) {
//互质
ans = max(ans, sp_max[b[i]] + sp_max[b[j]] );
}
}
}
cout << ans << endl;
}
int main(){
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t;
cin >> t ;
while(t--) solve();
return 0;
}
E
题目大意:
给一个x序列,代表餐厅的价格
给一个y序列,代表这些人兜里有多少钱
询问,这些人两两组队或者多人组队,最多可以去这些餐馆多少天?
思路:用yi-xi排序, 左边得到的是穷人,数组右边的是富人。富人能带一个穷人就算赢一天。
AC代码:
#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; i ++)
#define endl '\n'
#define x first
#define y second
using namespace std;
typedef pair<int, int> pii;
const int N = 2e5 + 5, INF = 0x3f3f3f3f;
//函数内初始化数组={}
struct node{
int x, y, substract;
}a[100005];
bool cmp(struct node &a, struct node &b){
return a.substract < b.substract;
}
void solve(){
int n;
cin >> n;
for(int i = 1; i <= n; i ++) cin >> a[i].x;
for(int j = 1; j <= n; j ++) cin >> a[j].y;
for(int i = 1; i <= n; i ++) a[i].substract = a[i].y - a[i].x;//输入数据,求出yi - xi的差值
sort(a + 1, a + 1 + n, cmp);
//双指针扫描
int ans = 0;
for(int i = 1, j = n; i < j; i ++){
if(a[i].y + a[j].y >= a[i].x + a[j].x) {
ans ++;
j --;
}
}
cout << ans << endl;
}
int main(){
cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
int t;
cin >> t;
while(t--) solve();
return 0;
}