F. Rudolf and Imbalance
题目大意:
给n,m,k三个整数
然后输入长度分别为n,m,k的三个整数数组a,d,f。然后a数组是有序递增的,问你往a数组中插入一个d[i]+f[j]使得a数组中的相邻两项的差的最大值最小化,还可以不插入,插入一个或者不插入,使得a数组中的相邻两项的差的最大值最小化。
题目做法:
插入一次只能改变一个相邻两项差,要使得影响最大,显然想到往原本差最大的两项中间差,且插入的值越接近两项的中央越好,好平的思路的F,接下来就是代码实现了。用二分去找这个最接近中央的值。时间复杂度 ,显然没问题。
AC代码:
#include<bits/stdc++.h>
#define pb(element) push_back(element)
#define fast ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
using namespace std;
const int maxn=1e5+100;
void solve()
{
int n,m,k;
set<int> ss;
cin>>n>>m>>k;
int a[n],d[m],f[k+1],large,seclarge;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<m;i++) cin>>d[i];
for(int i=0;i<k;i++) cin>>f[i];
sort(d,d+m);
sort(f,f+k);
f[k]=1e17;
int ps=0;
map<int,int> mp;
for(int i=0;i<n-1;i++)
{
ss.insert(abs(a[i+1]-a[i]));
mp[abs(a[i+1]-a[i])]++;
if(abs(a[i+1]-a[i])>=abs(a[ps+1]-a[ps]))
{
ps=i;
}
}
auto its=ss.end();
its--;
if(ss.size()==1)
{
seclarge=large=*its;
}
else
{
large=*its;
its--;
seclarge=*its;
}
if(mp[abs(a[ps+1]-a[ps])]!=1)
{
cout<<abs(a[ps+1]-a[ps])<<'\n';
}
else
{
int go=(a[ps+1]+a[ps])/2,di=d[0]+f[0];
for(int i=0;i<m;i++)
{
int div1,div2;
if(d[i]>=go) div1=d[i]+f[0],div2=d[i]+f[0];
else
{
int inips=lower_bound(f,f+k+1,go-d[i])-f;
div1=d[i]+f[inips];
div2=d[i]+f[inips];
if(inips!=0) div2=d[i]+f[inips-1];
}
if(abs(div2-go)<abs(di-go))
{
di=div2;
}
if(abs(div1-go)<abs(di-go))
{
di=div1;
}
}
go=(a[ps+1]+a[ps])/2+1;
int div=d[0]+f[0];
for(int i=0;i<m;i++)
{
int div1,div2;
if(d[i]>=go) div1=d[i]+f[0],div2=d[i]+f[0];
else
{
int inips=lower_bound(f,f+k+1,go-d[i])-f;
div1=d[i]+f[inips];
div2=d[i]+f[inips];
if(inips!=0) div2=d[i]+f[inips-1];
//cout<<div1<<" "<<div2<<'\n';
}
if(abs(div2-go)<abs(div-go))
{
div=div2;
}
if(abs(div1-go)<abs(div-go))
{
div=div1;
}
}
int modidif=min(max(abs(a[ps+1]-div),abs(a[ps]-div)),max(abs(a[ps+1]-di),abs(a[ps]-di)));
//cout<<modidif<<" "<<di<<'\n';
if(seclarge!=large) cout<<max({min(modidif,large),seclarge})<<'\n';
else cout<<max({min(modidif,large)})<<'\n';
}
}
signed main()
{
fast int casen=1;
cin>>casen;
while(casen--) solve();
}
A. XXXXX
原题链接:https://codeforces.com/contest/1364/problem/A
题目大意:
给一个数组,问最长的subarry其和不被x整除,问这个最长的subarry的长度。
题目做法:
很平的思路,如果本身总和就满足,则输出,如果不满足,其中所有元素都被x整除则为-1。
剩余情况就是从头或者尾开始,删到第一关不被x整除的数为止,要求删得尽量少。
AC代码:
def solve():
n, x = map(int, input().split())
ar = list(map(int, input().split()))
sum = 0
flag = 0
for i in ar:
sum += i
if(i % x != 0): flag = 1
if(sum % x != 0): print(n)
elif(sum % x == 0 and flag == 0): print("-1")
else:
front = 0
back = 0
for i in range(0, n):
if(ar[i] % x != 0):
front = i
break
for i in range(n-1, -1, -1):
if(ar[i] % x != 0):
back = i
break
# print(n, front, n - front - 1, back)
print(max(n - front - 1, back))
casen = int(input())
for i in range(0, casen): solve()
啥时候我的python也能像c++一样熟练啊。。。。。
B. Most socially-distanced subsequence
题目大意:
有一个全排列,要求你从其中选取一个subsequence满足如下条件
题目做法:
只有峰值需要被考虑,峰值到峰值间的数影响会被峰值覆盖。
比A还简单,就是我python真的,我真不想学python吧。。。。。
AC代码:
def solve():
n = int(input())
ar = list(map(int, input().split()))
res = []
res.append(ar[0])
if(ar[0] > ar[0 + 1]): up = 1
else: up = 0
for i in range(1, n - 1):
if(ar[i] > ar[i + 1]):
if(up == 0): res.append(ar[i])
up = 1
else:
if(up == 1): res.append(ar[i])
up = 0
res.append(ar[n - 1])
print(len(res))
for i in res:
print(i,end = ' ')
print('\n')
casen = int(input())
for i in range(0, casen): solve()