目录
第3题Burenka Plays with Fractions(900)
第6题Friends and the Restaurant(1200)
第9题Min-Max Array Transformation(1400)
第12题Parity Shuffle Sorting(1300)
第13题Meeting on the Line (1600)
第16题Good Subarrays (Easy Version)(1300)
第1题Mathematical Circus(800)
标签:建设型算法、数学
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T;
cin>>T;
while(T--){
int n, k;
cin>>n>>k;
//根据k%4分成4种情况
//设x为(a+k)
//(a+k)或者b中的任意一个%4=0,则一定可以配对
//若 (a+k)和b两个都是%4=2(两个都不是4的倍数的整数),则一定可以配对
//因此要满足配对有两种情况:(1)4的倍数带一个奇数(2)两个都是%4=2
//因此奇数a必须要(1)+k后变成%4=2 或者(2)+k后变成%4=0 或者(3)+k后仍然是奇数,但能b%4=0
// if(k%4 == 0) puts("NO"); //必然存在无法配对的奇数
// else if(k%4 == 1 || k%4 == 3) //奇数加上k后变成偶数,两个偶数能满足配对
// {
// puts("YES");
// for(int i=0; i+4<=n; i+=4)
// {
// printf("%d %d\n", i+1, i+2); //两个偶数
// printf("%d %d\n", i+3, i+4); //4带奇数
// }
// if(n%4 == 2) //n是偶数,但不一定是4的倍数,此时就多出来两个
// printf("%d %d\n", n-1, n); //两个偶数
//
// }
// else if(k%4 == 2) //将%4=2的偶数变成%4=0,这样就能带奇数
// {
// puts("YES");
// for(int i=0; i+4<=n; i+=4)
// {
// printf("%d %d\n", i+2, i+1); //4带奇数
// printf("%d %d\n", i+3, i+4); //4带奇数
// }
// if(n%4 == 2)
// printf("%d %d\n", n, n-1); //4带奇数
// }
//第二遍
if(k%4==0) puts("NO");
else if(k%4==1){
puts("YES");
for(int i=0; i+4<=n; i+=4)
{
printf("%d %d\n", i+3, i+1);
printf("%d %d\n", i+2, i+4);
}
if(n%4==2) printf("%d %d\n", n-1, n);
}
else if(k%4==2){
puts("YES");
for(int i=0; i+4<=n; i+=4)
{
printf("%d %d\n", i+2, i+3);
printf("%d %d\n", i+1, i+4);
}
if(n%4==2) printf("%d %d\n", n, n-1);
}
else if(k%4==3){
puts("YES");
for(int i=0; i+4<=n; i+=4)
{
printf("%d %d\n", i+1, i+3);
printf("%d %d\n", i+2, i+4);
}
if(n%4==2) printf("%d %d\n", n-1, n);
}
}
return 0;
}
第2题Fighting Tournament(1400)
标签:二分、数据结构、执行、双指针
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int main()
{
int T;
cin>>T;
while(T--){
//第一遍
// int a[N], first[N], cnt[N], whowin[N];
// memset(a, 0, sizeof a); //实力(强度值),下标是位置
// memset(first, 0, sizeof first); //第一次赢的轮数,下标是实力
// memset(cnt, 0, sizeof cnt); //赢了多少次,下标是实力
// memset(whowin, 0, sizeof whowin); //这一轮赢了的实力是多少,下标是轮数
// int n, q;
// cin>>n>>q;
// for(int i=1; i<=n; i++) scanf("%d", &a[i]);
//
// //预处理
// int now = a[1]; //现在赢了的实力是多少
// for(int i=2; i<=n; i++)
// {
// if(a[i] > now) now = a[i];
// if(first[now] == 0) first[now] = i-1; //记录的是轮数,要-1
// cnt[now]++;
// whowin[i-1] = now; //下标是轮数,要-1
// }
//
// //询问(时间复杂度为O(1)
// while(q--)
// {
// int x, k;
// scanf("%d%d", &x, &k);
//
// int ans = 0;
// x = a[x];
// if(k <= n-1)
// {
// if(whowin[k] < x) ans = 0;
// else if(whowin[k] == x) ans = k-first[x]+1;
// else ans = cnt[x];
// }
// else ans = cnt[x] + ((x==n) ? (k-n+1) : 0); //太妙了!!
// cout<<ans<<endl;
// }
//第二遍
int a[N], cnt[N], first[N], who[N]; //赢的次数,第一次赢的轮数、这一轮谁赢了
memset(a, 0, sizeof a);
memset(cnt, 0, sizeof cnt);
memset(first, 0, sizeof first);
memset(who, 0, sizeof who);
int n, q;
cin>>n>>q;
for(int i=0; i<n; i++) cin>>a[i];
pair<int, int> maxs = {a[0], 0}; //力量、位置
for(int i=1; i<n; i++)
{
if(a[i] > maxs.first) maxs = {a[i], i};
who[i] = maxs.second; //从1开始
cnt[maxs.second]++;
if(!first[maxs.second]) first[maxs.second] = i;
}
while(q--)
{
int t, k;
cin>>t>>k;
int ans = 0;
if(k <= n-1) //n个选手只有n-1轮,比赛轮数是从1开始
{
if(a[t-1] > a[who[k]]) ans = 0;
else if(a[t-1] == a[who[k]]) ans = k-first[t-1]+1;
else ans = cnt[t-1];
}
else
{
ans = cnt[t-1];
if(t-1 == maxs.second) ans += k-(n-1);
}
cout<<ans<<endl;
}
}
return 0;
}
第3题Burenka Plays with Fractions(900)
标签:数学、数论
//A
//操作两次,就可以将两个分数的分子变成0,因此最多操作2步,使x==y
//1。操作0次:x==y
//2。(1)操作1次:(ax)/b==c/d,那么就只需要a乘上x,x必须是整数,因此当x=(bc)/(ad)为整数时,操作1次
// (2)a/b==(cx)/d同理, x=(ad)/(bc)是整数时,操作1次
// (3)也就是说:bc和ad能能被另一个整除的话,就操作1次
// (4)0对任何数取模都是0(任何数对0取模会直接报错不输出,容易出bug),因此要特判是0的情况
//3。剩下的情况就是操作两次了
#include<bits/stdc++.h>
#define LL long long
using namespace std;
//typedef long long LL;
int main()
{
int T;
cin>>T;
while(T--)
{
int a, b, c, d;
cin>>a>>b>>c>>d;
LL x = (LL)a*d, y = (LL)b*c; //要开LL,不然两个1e9相乘会爆int,计算过程中也要开LL,不然两个int相乘后他会自动变回int,若相乘结果爆int,变回int时就会出错
if(x == y) cout<<0<<endl;
else if(a==0 || c==0 || x%y==0 || y%x==0) cout<<1<<endl;
else cout<<2<<endl;
}
return 0;
}
第4题Best Permutation(800)
标签:建设性算法、贪心
//
#include <bits/stdc++.h>
#define first fi
#define second se
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 110;
int n;
int a[N];
bool st[N];
int dfs(int u)
{
if(u == n-2+1)
{
int x = 0;
for(int i=1; i<=n; i++)
{
if(x < a[i]) x += a[i];
else x = 0;
}
if(x == 2*n-1) return 1;
return 0;
}
for(int i=1; i<=n; i++)
{
if(st[i]) continue;
a[u] = i;
st[i] = true;
if(dfs(u+1)) return 1;
st[i] = false;
}
return 0;
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
memset(st, 0, sizeof st);
a[n-1] = n-1, a[n] = n; //这个就是解题关键点
st[n-1] = st[n] = true;
dfs(1);
for(int i=1; i<=n; i++) cout<<a[i]<<" ";
cout<<endl;
}
return 0;
}
第5题Digital Logarithm(1400)
标签:数据结构、贪心、排序
//如果最大的数成对,就消掉,否则f()
//不断在最大元素上重复f()操作即可
#include <bits/stdc++.h>
#define first fi
#define second se
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
multiset<int, greater<int>> a, b; //从大到小排序
for(int i=0; i<n; i++)
{
int x;
scanf("%d", &x);
a.insert(x);
}
for(int i=0; i<n; i++)
{
int x;
scanf("%d", &x);
b.insert(x);
}
int res = 0;
while(a.size())
{
if(*a.begin() == *b.begin()) //a.begin()好像是指针,必须要加*
{
a.erase(a.begin());
b.erase(b.begin());
continue;
}
if(*a.begin() > *b.begin())
swap(a, b);
int x = *b.begin();
b.erase(b.begin()); //erase()的参数是指针,所以这里只能写b.begin(),不能写x
b.insert(to_string(x).length());
res++;
}
cout<<res<<endl;
}
return 0;
}
第6题Friends and the Restaurant(1200)
标签:贪心、双指针
//本题核心就是不一定一个正值要带两个负值的,我就只带一个,另一个遗弃掉
//lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,
//找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
//upper_bound( begin,end,num):查找第一个大于num的数字
//lower_bound( begin,end,num,greater<type>() ):查找第一个小于或等于num的数字
//upper_bound( begin,end,num,greater<type>() ):查找第一个小于num的数字
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T;
cin>>T;
while(T--){
int n;
cin>>n;
vector<int> x(n); //x(n);
for(int i=0; i<n; i++) cin>>x[i];
for(int i=0; i<n; i++){
int y;
cin>>y;
x[i] = y-x[i];
}
sort(x.begin(), x.end());
//第一种方式
int ans = 0;
int p = lower_bound(x.begin(), x.end(), 0)-x.begin(); //二分查找第一个大于或等于0的数字
for(int i=0, j=n-1; i<p; i++)
{
if(j>=p && x[j]+x[i]>=0)
{
ans++;
j--;
}
}
ans += (n-ans-p)/2; //==((n-1)-ans-p+1)/2;
cout<<ans<<endl;
//第二种方式
// int ans = 0;
// for(int i=0, j=n-1; i<j; j--)
// {
// while(i<j && x[i]+x[j]<0) i++;
// if(i<j && x[i]+x[j]>=0)
// {
// ans++;
// i++;
// }
// }
// cout<<ans<<endl;
}
return 0;
}
第7题Jumping on Tiles(1100)
标签:建设性算法、字符串
//
#include <bits/stdc++.h>
#define first fi
#define second se
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N=200010;
int main()
{
int T;
cin>>T;
while(T--)
{
string s;
cin>>s;
vector<int>q[26];
int n = s.length();
for(int i=0; i<n; i++) q[s[i]-'a'].push_back(i+1);
int x = s[0]-'a', y = s[n-1]-'a';
vector<int> ans;
if(x < y)
for(int i=x; i<=y; i++)
ans.insert(ans.end(), q[i].begin(), q[i].end());
else if(x > y)
for(int i=x; i>=y; i--)
ans.insert(ans.end(), q[i].begin(), q[i].end());
else if(x == y)
ans.insert(ans.end(), q[x].begin(), q[x].end());
printf("%d %d\n", abs(x-y), ans.size());
for(int i=0; i<int(ans.size()); i++) //ans.size()返回不是int
printf("%d ", ans[i]);
cout<<endl;
}
return 0;
}
第8题Not a Cheap String(1000)
标签:贪心
(和第7题类似)
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
int main()
{
cin.tie(0); //优化
int T;
cin>>T;
while(T--)
{
//tourist的方法,和jiangly好像
// string w;
// int p;
// cin>>w>>p;
//
// int n = w.size();
// vector<vector<int>> a(26);
// int sum = 0;
// for(int i=0; i<n; i++)
// {
// a[w[i]-'a'].push_back(i);
// sum += w[i]-'a'+1;
// }
// vector<bool> st(n, false); //记住这个语法
// for(int i=25; i>=0; i--)
// {
// while(sum>p && !a[i].empty())
// {
// sum -= i+1;
// st[a[i].back()] = true;
// a[i].pop_back();
// }
// }
//
// for(int i=0; i<n; i++)
// if(!st[i])
// cout<<w[i];
// cout<<endl;
//自己的方法
string w;
int p;
cin>>w>>p;
int n = w.length();
vector<bool> st(n, false);
vector<PII> q(n);
for(int i=0; i<n; i++) q[i] = {w[i]-'a'+1, i};
sort(q.begin(), q.end(), greater<PII>());
int sum = 0;
for(int i=0; i<n; i++) sum += q[i].first;
for(int i=0; i<n; i++)
{
if(sum <= p) break;
sum -= q[i].first;
st[q[i].second] = true; //不明白为什么说这里可能越界
}
for(int i=0; i<n; i++)
if(!st[i])
cout<<w[i];
cout<<endl;
}
return 0;
}
第9题Min-Max Array Transformation(1400)
标签:二分、贪心、双指针
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
vector<int>a(n), b(n);
for(int i=0; i<n; i++) cin>>a[i];
for(int i=0; i<n; i++) cin>>b[i];
for(int i=0; i<n; i++)
{
//第一种方法
int p = lower_bound(b.begin(), b.end(), a[i])-b.begin(); //第一个大于等于a[i]的
cout<<b[p]-a[i]<<" ";
//第二种(双指针)
// int j = 0;
// while(b[j]<a[i]) j++;
// cout<<b[j]-a[i]<<" ";
}
puts("");
for(int i=0, j=0; i<n; i++)
{
j = max(j, i);
while(j+1<n && b[j]>=a[j+1]) j++;
cout<<b[j]-a[i]<<" ";
}
puts("");
}
return 0;
}
第10题Double Strings(1100)
标签:暴力、数据结构、字符串
TLE代码///
//#include<bits/stdc++.h>
//using namespace std;
//bool check(string &str, vector<string>&s, vector<vector<string>>& map)
//{
// int len = str.length();
// for(int i=1; i<len; i++)
// {
// for(auto t1:map[i])
// {
// for(auto t2:map[len-i])
// {
// if(str == t1+t2) return true;
// }
// }
// }
// return false;
//}
//int main()
//{
// int T;
// cin>>T;
// while(T--)
// {
// int n;
// cin>>n;
// vector<string> s(n);
// vector<vector<string>> map(9); //从0开始,因此8+1
// for(int i=0; i<n; i++)
// {
// cin>>s[i];
// map[s[i].size()].push_back(s[i]);
// }
//
// for(int i=0; i<n; i++)
// {
// if(check(s[i], s, map)) cout<<1;
// else cout<<0;
// }
// puts("");
// }
// return 0;
//}
//第一种方法(和上面的很像,只不过优化了一下)///
//string sub1 = s.substr(5); //只有一个数字5表示从下标为5开始一直到结尾:sub1 = "56789"
//string sub2 = s.substr(5, 3); //从下标为5开始截取长度为3位:sub2 = "567"
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
// vector<string> s(n);
string s[n]; //也可以
map<string, bool> mp; //map的使用和unordered_map类似
for(int i=0; i<n; i++)
{
cin>>s[i];
mp[s[i]] = true;
}
for(int i=0; i<n; i++)
{
bool ok = false;
int len = s[i].length();
for(int j=1; j<len; j++)
{
string pre = s[i].substr(0, j); //注意substr()的用法
string stuff = s[i].substr(j, len-j);
if(mp[pre] && mp[stuff])
{
ok = true;
break;
}
}
if(ok) cout<<1;
else cout<<0;
}
puts("");
}
return 0;
}
第11题Mainak and Array(900)
标签:贪心、数学
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
vector<int> a(n);
for(int i=0; i<n; i++){
cin>>a[i];
}
int ans = a[n-1] - a[0];
for(int i=0; i<n-1; i++){
ans = max(ans, a[n-1]-a[i]);
}
for(int i=0; i<n; i++){
ans = max(ans, a[i]-a[0]);
}
for(int i=0; i<n-1; i++){ //特殊情况
ans = max(ans, a[i]-a[i+1]);
}
cout<<ans<<endl;
}
return 0;
}
第12题Parity Shuffle Sorting(1300)
标签:建设性算法、排序
//相同奇偶性的两个数相加为偶数,不同奇偶性相加则为奇数
//原理自己看代码吧
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
int main()
{
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
vector<int> a(n);
for(int i=0; i<n; i++) cin>>a[i];
if(n == 1) cout<<0<<endl;
else
{
int cnt = 0;
vector<int> l(n), r(n);
int idx = 0;
int x = 0;
for(int i=1; i<n; i++)
if((a[0]+a[i])%2 == 0) //找到最后一个与第一个相同奇偶性的下标
x = i;
for(int i=0; i<x; i++) //不是i<n,是i<x,所有x之前的
if((a[x]+a[i])%2 == 0)
{
a[i] = a[x]; //将于所有与第一个元素相同奇偶性的数改变成a[x]
l[idx] = i, r[idx++] = x;
cnt++;
}
for(int i=1; i<n; i++)
if((a[0]+a[i])%2 == 1)
{
a[i] = a[0]; //将于所有与第一个元素不相同奇偶性的数改变成a[x]
l[idx] = 0, r[idx++] = i;
cnt++;
}
cout<<cnt<<endl;
for(int i=0; i<cnt; i++)
printf("%d %d\n", l[i]+1, r[i]+1);
}
}
return 0;
}
第13题Meeting on the Line (1600)
标签:二分、贪心、执行、数学、三分搜索
//一定要注意:本题不是让所有人的时间最小,而是让最大值最小
//如果所有t=0,就是一个经典的问题,答案就是:就是最大和最小坐标的平均值
//我们可以把t加入到x中来将问题转化成这个经典问题:
/*
将(xi, ti)转化成(xi-ti, 0)和(xi+ti, 0)
然后遍历所有i,找出最小的xi-ti,就变成了转化后的最小位置
同理,找出最大的xi+ti,就变成了转化后的最大位置
*/
#include<bits/stdc++.h>
using namespace std;
const int inf = 1e9;
const int N = 200010;
int s[N];
void solve()
{
int n;
cin>>n;
vector<int> x(n), t(n);
for(int i=0; i<n; i++) cin>>x[i];
int mi = inf, mx = -inf;
for(int i=0; i<n; i++)
{
cin>>t[i];
mi = min(mi, x[i] - t[i]);
mx = max(mx, x[i] + t[i]);
}
printf("%.7lf\n", (double)(mi+mx)/2); //要求小数点后6位
}
int main()
{
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
第14题Reset K Edges(1900)
标签:二分、dfs、图论、贪心、树
本题做法就是二分,遇到深度为mid-1的就割掉
//实现方式一:用dfs求子树深度
#include<bits/stdc++.h>
using namespace std;
int n, k;
vector<int> edge[200010];
int step;
int mid;
int dfs(int u, int fa)
{
int depth = 0;
for(int i=0; i<edge[u].size(); i++)
{
int v = edge[u][i];
int de = dfs(v, u);
depth = max(depth, de+1);
}
if(u > 1 && depth == mid-1) //当这课树的深度为depth-1,那么这棵树就和父节点的边割掉,例如:4变成2和1
{
if(fa != 1) step++; //和根节点无论怎么割深度都是1
return -1; //和+1相加变成0,也就是舍弃这个子树了
}
else
return depth;
}
bool check()
{
step = 0;
dfs(1, 0);
return step <= k;
}
void solve()
{
cin>>n>>k;
for(int i=1; i<=n; i++) edge[i].clear();
for(int i=2; i<=n; i++)
{
int x;
scanf("%d", &x);
edge[x].push_back(i);
}
int l = 1, r = n-1; //高度范围是[1, n-1]
while(l < r)
{
mid = l + r >> 1;
if(check()) r = mid;
else l = mid+1;
}
cout<<l<<endl;
}
int main()
{
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
//实现方式二:从下往上构建树
#include<bits/stdc++.h>
using namespace std;
void solve()
{
int n, k;
cin>>n>>k;
vector<int> p(n+1);
for(int i=2; i<=n; i++)
cin>>p[i];
int l = 1, r = n-1; //高度范围是[1, n-1]
while(l < r)
{
int mid = l + r >> 1;
int step = 0;
vector<int> h(n+1);
for(int i=n; i>=2; i--)
{
if(h[i]==mid-1 && p[i]!=1) //p[i]!=1:和根节点无论怎么割深度都是1 //当这课树的深度为mid-1,那么这棵树就和父节点的边割掉,例如:4变成2和1
step++;
else
h[p[i]] = max(h[p[i]], h[i]+1);
}
if(step <= k) r = mid;
else l = mid+1;
}
cout<<l<<endl;
}
int main()
{
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
第15题Phase Shift(1400)
标签:dfs、dsu、图标、贪心、字符串
#include<bits/stdc++.h>
using namespace std;
vector<int> c(26, -1); //被谁指
vector<int> fc(26, -1); //指向谁
vector<int> sz(26, 1); //当前链的字符个数
vector<int> p(26); //当前链的祖字符
int find(int x)
{
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
void solve()
{
int n;
cin>>n;
string s;
cin>>s;
for(int i=0; i<26; i++)
{
c[i] = -1;
fc[i] = -1;
sz[i] = 1;
p[i] = i;
}
for(int i=0; i<n; i++)
{
int t = s[i]-'a';
if(c[t] == -1)
{
for(int j=0; j<26; j++)
if(fc[j]==-1 && (find(j)!=find(t) || sz[t]==26))
{
c[t] = j;
fc[j] = t;
p[t] = find(j);
sz[find(j)] += sz[t];
break;
}
}
printf("%c", c[t]+'a');
}
cout<<endl;
}
int main()
{
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
第16题Good Subarrays (Easy Version)(1300)
标签:二分、数据结构、双指针
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
void solve()
{
int n;
cin>>n;
vector<int> a(n);
for(int i=0; i<n; i++) cin>>a[i];
LL res = 0;
int l = 0;
for(int r=0; r<n; r++)
{
l = max(l, r-(a[r]-1)); //主要就是这里 //取max是因为l只能增大
res += r-l+1;
// printf("l:%d r:%d res:%lld\n", l, r, res);
}
cout<<res<<endl;
}
int main()
{
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
第17题Coprime(1100)
标签:暴力、贪心、数论
第一种实现方式
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
vector<int> p[1010];
void solve()
{
int n;
cin>>n;
vector<int> id[1010];
for(int i=1; i<=n; i++)
{
int x;
cin>>x;
id[x].push_back(i); //存入每个数出现的下标
}
int res = -1;
for(int i=1; i<=1000; i++)
if(!id[i].empty())
for(int j : p[i])
if(!id[j].empty())
res = max(res, id[i].back()+id[j].back()); //取下标最大的两个
cout<<res<<endl;
}
int main()
{
for(int i=1; i<=1000; i++)
for(int j=1; j<=1000; j++)
if(__gcd(i, j) == 1) //直接调用自带的:__gcd()
p[i].push_back(j); //预处理出来互为质数的两个数
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
/第二种方式/
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int gcd(int a, int b)
{
return b ? gcd(b, a%b) : a;
}
void solve()
{
int n;
cin>>n;
vector<int> id(1010, 0);
for(int i=1; i<=n; i++)
{
int x;
cin>>x;
id[x] = i; //存储每个数最大的下标
}
int res = -1;
for(int i=1; i<=1000; i++)
for(int j=1; j<=1000; j++)
if(gcd(i, j)==1 && id[i]!=0 && id[j]!=0)
res = max(res, id[i]+id[j]);
cout<<res<<endl;
}
int main()
{
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}
第18题Smaller(1500)
标签:构造算法、贪心、字符串
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 10;
void solve()
{
bool sta = false, stb = false; //a,b字符串中是否存在>'a'的字符
LL cnta = 0, cntb = 0; //=='a'的字符数量 //可能会爆int
int q;
cin>>q;
while(q--)
{
int d, k;
string x;
cin>>d>>k>>x;
for(auto c : x)
{
if(d == 1)
{
if(c > 'a') sta = true;
else cnta += k;
}
else
{
if(c > 'a') stb = true;
else cntb += k;
}
}
if(stb) //b字符串中有>'a'的字符,则a<b
puts("YES");
else if(!sta && cnta<cntb) //b中全是'a',那么就比较a和b中的'a'的数量(且前提是a中也全是'a')
puts("YES");
else
puts("NO");
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
solve();
}
return 0;
}