A:思维
题意:给一定的N*N的板子,里面放有一些乌鸦,这些乌鸦会攻击自己的所在行与所在列,问给定一个数量的乌鸦,问是否能够移动某只乌鸦,使得形成和平局面?
方法:我们发现,N*N的板子,因为乌鸦会攻击所在行与所在列,所以要形成和平局面,则最多只能放N只乌鸦,如果多余了N只,那么肯定不会形成和平局面。所以,这题只跟板子的大小和乌鸦的数量有关。
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
inline void solve(){
int n,m;cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;cin>>x>>y;
}
if(m<n)cout<<"YES\n";
else cout<<"NO\n";
}
signed main(){
int T;cin>>T;
while(T--) solve();
}
B:贪心
题意:给定N个具有一定顺序排列的怪物,这个怪物本身有血量,还有一个技能,就是在这个怪物死后,发动这个技能会使他左右两边的怪物加上一定的血量。定义怪物的血量为HP的话,那么杀死这个怪物所用的时间就需要HP秒,这一个怪物死后,就消失了。他左右的邻居就相邻了。
问如何一个一个的杀完所有的怪物使得用的时间最短?
方法:因为杀死一个怪物,它的左右邻居都会加上一定血量,那么要想所有怪物的血量加的最少,则应该从第一个或者最后一个怪物开始杀起,因为他们的邻居只有1个,这样尽可能少的给怪物加血量。我们知道,杀完所有怪物(若所有怪物的加血技能都加0滴血),那么所需要的时间,就是所有怪物的血量和:SUM。若所有怪物的加血技能都加不为0的血量时,则所需要的最少时间一定是SUM+(N-1)个怪物的加血量。因为最后一个怪物死后,它的加血技能没有用,所以我们最优的方案一定是将加血量最多的怪物放在最后一个消灭。
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
inline void solve(){
int res=0,maxx=0;
int n;cin>>n;
for(int i=1;i<=n;i++){
int x;cin>>x;
res+=x;
}
for(int i=1;i<=n;i++){
int x;cin>>x;
res+=x;
maxx=max(maxx,x);
}
cout<<res-maxx<<"\n";
}
signed main(){
int T;cin>>T;
while(T--) solve();
}
C:暴力+贪心 or(二分+贪心)
题意:有n个数,Alice和Bob玩游戏。游戏进行k轮,每一轮Alice必须消除一个小于等于 k−i+1 的数,在消除之后,如果数组还有元素的话Bob需要对一个数增加 k−i+1 ,求Alice在保证自己在k轮内都能消除数的前提下,最多进行的轮次。
分析:Alice每消除一个数,Bob就会在剩余数组中选择一个数加k-i+1。随着轮次的增加,Alice消除的数是越来越小的。这里考虑一下贪心策略。
设想如果Bob选择的是数组中最大的数,那么Alice就肯定不会消除完所有的数,那么要想使得轮次更多,Bob选择数组中最小的数进行操作即可。
这里解释一下Bob的选择操作:为什么每次选最小数会使轮次增加?
选择最大的数进行操作是肯定不行的,那么选择次大数呢?这里不妨反演一遍,如果Bob每次都操作最小的数,那么最小数每次都在增大,则就一定会使轮次增大。
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[101];
inline bool pd(int k){
int l=1,r=n;
for(int i=1;i<=k;i++){
while(a[r]>k-i+1) r--;
//如果一开始就是小于最大值的话,我们就减减,为的是让这个k不满足pd
if(l>r) return false;//说明Bob的操作次数比Alice多,则就不可能满足pd
l++,r--;//Alice从右往左操作,Bob从左往右操作
}
return true;
}
inline void solve(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
int ans=0;
for(int i=1;i<=n;i++){//为什么要在1-n范围找呢?因为k-i+1的最小值只能为1而不能为0
if(pd(i)) ans=i;
}
cout<<ans<<"\n";
}
signed main(){
int T;cin>>T;
while(T--) solve();
}