A
思路:这题我感觉写复杂了。
我的思路是贪心:尽可能让所有的战机拿到贡献,并且在当前这辆战机在可以拿的贡献中拿最大的。
那么,先对自己的战机和敌人的战机按照防御值升序。
然后枚举自己的所有战机,因为敌人的战机已经排序了,我们二分出最后一个小于当前这辆战机的位置,然后在区间[1,index]找最大值。
这就是一个区间最大值的问题了,可以用线段树来维护一下就行了。
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
using namespace std;
const int maxn = 2e6 + 10;
typedef long long int ll;
struct node{
ll d,v;
}s[maxn];
ll a[maxn];
bool cmp(ll x,ll y){
return x < y;
}
bool cmp2(node x,node y){
return x.d < y.d;
}
#define lson (rt * 2)
#define rson (rt * 2 + 1)
int pos;
ll m[maxn];
void build(int l,int r,int rt){
if(l == r){
m[rt] = s[pos ++].v;
return ;
}
int mid = l + r >> 1;
build(l,mid,lson);
build(mid + 1,r,rson);
m[rt] = max(m[lson],m[rson]);
}
ll query(int l,int r,int ql,int qr,int rt){
if(l >= ql && r <= qr){
return m[rt];
}
int mid = l + r >> 1;
ll res = 0;
if(ql <= mid)res = max(res,query(l,mid,ql,qr,lson));
if(qr > mid)res = max(res,query(mid + 1,r,ql,qr,rson));
return res;
}
void solved(){
int n,m;scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++)scanf("%lld",&a[i]);
for(int i = 1; i <= m; i++)scanf("%lld",&s[i].d);
for(int i = 1; i <= m; i++)scanf("%lld",&s[i].v);
sort(a + 1,a + 1 + n,cmp);
sort(s + 1,s + 1 + m,cmp2);
pos = 1;
build(1,m,1);
ll ans = 0;
for(int i = 1; i <= n; i++){
int l = 1,r = m;
int index = -1;
while(l <= r){
int mid = l + r >> 1;
if(s[mid].d >= a[i]){
r = mid - 1;
}else{
index = mid;
l = mid + 1;
}
}
if(index == -1)continue;
ans += query(1,m,1,index,1);
}
printf("%lld\n",ans);
}
int main(){
solved();
return 0;
}E
思路:
先求出你和你朋友有多少个相同的题,那么你这个时候能对min(same,n - k)个,然后他错了几道题就意味着你对了几道题min(k,n - same)。
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
const int maxn = 2e5 + 10;
typedef long long int ll;
bool you[maxn],f[maxn];
void solved(){
int n,k;cin>>n>>k;
for(int i = 1; i <= n; i++)cin>>you[i];
for(int i = 1; i <= n; i++)cin>>f[i];
int same = 0;
for(int i = 1; i <= n; i++){
if(you[i] == f[i])same++;
}
cout<<min(n - k,same) + min(k,n - same) <<endl;
}
int main(){
solved();
return 0;
}G
思路:
随便玩几个样例就发现规律了。
n = 1
0
1
n = 2
0 [0]
0 [1]
1 [1]
n = 3
0 [0 0]
0 [0 1]
0 [1 1]
1 [1 1]
dp[i][0] = dp[i - 1][0] + dp[i - 1][1]
dp[i][1] = 1
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
const int maxn = 2e5 + 10;
typedef long long int ll;
ll mod = 998244353 ;
ll dp[maxn][2];
void solved(){
int n;cin>>n;
dp[1][0] = dp[1][1] = 1;
for(int i = 2; i <= n; i++){
dp[i][0] = (dp[i][0] + ((dp[i - 1][0] + dp[i - 1][1]) % mod)) % mod;
dp[i][1] += 1;
}
cout<<(dp[n][0] + dp[n][1]) % mod <<endl;
}
int main(){
solved();
return 0;
}H
思路:计算两个圆心距离,然后把外离与内含的情况去掉,其它均可。
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#include<map>
using namespace std;
const int maxn = 2e5 + 10;
typedef long long int ll;
void solved(){
ll x1,y1,r1,x2,y2,r2;
scanf("%lld%lld%lld%lld%lld%lld",&x1,&y1,&r1,&x2,&y2,&r2);
double d = sqrt(double((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
if(d > r1 + r2){
cout<<"NO"<<endl;return ;
}
if(d < abs(r1 - r2)){
cout<<"NO"<<endl;return ;
}
cout<<"YES"<<endl;
}
int main(){
int t;cin>>t;
while(t--)
solved();
return 0;
}D
思路:
可以知道m次是固定的就非叶子节点的数,并且我们知道,每次大园林剪或者小园林剪都会把根节点的值覆盖掉,那么我们可以知道,根节点最后的生命力的值一定是来自叶子节点,即非叶子节点的值其实是无用的。
那么我们只需要那大最大的叶子节点的贡献即是答案,要拿到某个叶子节点的值需要满足dep[u] <= 大林园剪的次数(一路大林园剪上去)
大园林剪的次数 = n - 叶子节点 对 2 向上取整。
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
const int maxn = 2e5 + 10;
typedef long long int ll;
ll G[maxn][2];
ll w[maxn];
int dep[maxn];
bool vis[maxn];
void dfs(int u,int de){
if(u == 0)return ;
dep[u] = de + 1;
dfs(G[u][0],de + 1);
dfs(G[u][1],de + 1);
}
void solved(){
int n;scanf("%d",&n);
int cnt = 0;
for(int i = 1; i <= n; i++){
int l,r;scanf("%d%d",&l,&r);
G[i][0] = l;G[i][1] = r;
if(l == r && l == 0)cnt++,vis[i] = true;
}
dfs(1,-1);
int k = n - cnt;k = (k + 1) / 2;
ll ans = 0;
for(int i = 1; i <= n; i++){
scanf("%lld",&w[i]);
if(vis[i] && dep[i] <= k){
ans = max(ans,w[i]);
}
}
cout<<ans<<endl;
}
int main(){
solved();
return 0;
}
京公网安备 11010502036488号