A 模拟样例发现n>2不可能 小于2时连续也不可能
# include <bits/stdc++.h>
using namespace std;
# define int long long
const int N=50;
signed main()
{
int t;
cin>>t;
while(t--)
{
int n;
int a[N]={0};
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
bool st=0;
if(n>2)
st=1;
else
{
if(a[1]==a[2]-1)
st=1;
}
if(st)
cout<<"NO";
else cout<<"YES";
cout<<endl;
}
}
B
分类讨论 如果两个区间一样则为区间差 如果区间不重叠则为1
下面考虑区间重叠 如果区间两个都端点都不相等端点外侧则可以各多占一个位置答案则为区间差+2,如果某个端点相等则那扇门后面将无法站人答案则为区间差+1
# include <bits/stdc++.h>
using namespace std;
# define int long long
# define x first
# define y second
typedef pair<int,int>PII;
signed main()
{
int t;
cin>>t;
while(t--)
{
vector<PII>v;
for(int i=1;i<=2;i++)
{
int a,b;
cin>>a>>b;
v.push_back({a,b});
}
sort(v.begin(),v.end());
if(v[0]==v[1])
cout<<v[0].y-v[0].x;
else
{
if(v[1].x>v[0].y)
cout<<1;
else
{
int x1=max(v[0].x,v[1].x),x2=min(v[0].y,v[1].y);
if(v[0].x==v[1].x||v[1].y==v[0].y)
cout<<abs(x2-x1)+1;
else cout<<abs(x2-x1)+2;
}
}
cout<<endl;
}
}
C 本题考查贪心 1要求答案尽可能大2要求答案尽可能小 则1会选取最大,2会选取次大值。对于2的次大值有k个之可以将其转化为更大的值最优为次大值等于最大值,然后从后往前依次模拟即可
注意特判i等于1时候
# include <bits/stdc++.h>
using namespace std;
# define int long long
# define x first
# define y second
const int N=2e5+10;
signed main()
{
int t;
cin>>t;
while(t--)
{
int n,k,a[N]={0};
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
int sum=0;
for(int i=n;i>=1;i-=2)
{
if(i==1)
{
sum+=a[1];
break;
}
if(a[i]-a[i-1]<=k)
k=k-(a[i]-a[i-1]);
else if(a[i]-a[i-1]>k)
sum+=a[i]-k-a[i-1],k=0;
}
cout<<sum;
cout<<endl;
}
return 0;
}
D 与最短路无关,考察分类讨论。首先我们根据性质可知最多我们转站一次 如果x y之间可直接到达则花销最小 否则我们去枚举 x y之间所能构成的字符 然后用字符去找中转站。
对于中转站有三种情况
1.编号在下x,y之间则但答案为y-x
2.编号在x左侧 则找到第一个大于x的地址向前移动一个位置所代表的表编号答案为x + y - 2 * (*lo) 右侧同理取绝对值即可
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5 + 10,inf = 1e18;
int n, q;
map<string, vector<int>> S;
string s[N];
void solve()
{
cin >> n >> q;
for (int i = 1; i <= n; i ++)
cin >> s[i], S[s[i]].push_back(i);
while (q -- )
{
int x, y;
cin >> x >> y;
if (x > y) swap(x, y);
int res = inf;
for (auto i : s[x])
for (auto j : s[y])
{
if (i == j)
{
res = min(res, y - x);
break;
}
string tp = ""; tp += i, tp += j;
//cout<<tp<<" ";
if (tp[0] > tp[1]) swap(tp[0], tp[1]);
auto mid = lower_bound(S[tp].begin(), S[tp].end(), x);
if (mid != S[tp].end() && (*mid) <= y)
res = min(res, y - x);
auto lo = mid, ro = upper_bound(S[tp].begin(), S[tp].end(), y);
if (lo != S[tp].begin())
lo --, res = min(res, x + y - 2 * (*lo));
if (ro != S[tp].end())
res = min(res, 2 * (*ro) - x - y);
}
if (res == inf) cout << -1 << endl;
else cout << res << endl;
}
S.clear();
}
signed main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int dt;
cin >> dt;
while (dt --)
solve();
return 0;
}