​第 257 场周赛​

​1. 统计特殊四元组3​​ 思路:数据量很小,暴力

int countQuadruplets(vector<int>& nums) {
int ans=0;
int n = nums.size();
for(int k=n-1;k>=3;k--){
for(int i=0;i<k;i++){
for(int j=i+1;j<k;j++){
for(int x=j+1;x<k;x++){
if(nums[i]+nums[j]+nums[x]==nums[k]) ans++;
}
}
}
}
return ans;
}

​2. 游戏中弱角色的数量4​​ 思路:1、排序+条件暴力 2、排序+单调栈

1、排序+暴力
= =。其实就是对每个attack排序 在对defensei 排序 在把每个i 的相对位置 加起来 角色 i 弱于 存在的另一个角色 j 那么val[i]<val[j] 再倒着找一下 (不是个好办法= =)

class Solution {
public:
struct node{
int val;
int a,d;
};
static bool cmp1(node x,node y){
return x.a<y.a;
}
static bool cmp2(node x,node y){
return x.d<y.d;
}
static bool cmp3(node x,node y){
return x.val<y.val;
}
int numberOfWeakCharacters(vector<vector<int>>& properties) {
int n = properties.size();
vector<node> pro(n);
for(int i=0;i<n;i++){
pro[i].a = properties[i][0];
pro[i].d = properties[i][1];
pro[i].val=0;
}
sort(pro.begin(),pro.end(),cmp1);
int cnt=1;
for(int i=0;i<n;i++) {
if(i==0) pro[i].val=cnt;
else{
if(pro[i].a==pro[i-1].a) pro[i].val=cnt;
else cnt++,pro[i].val=cnt;
}

}
sort(pro.begin(),pro.end(),cmp2);
cnt=1;
for(int i=0;i<n;i++) {
if(i==0) pro[i].val+=cnt;
else{
if(pro[i].d==pro[i-1].d) pro[i].val+=cnt;
else cnt++,pro[i].val+=cnt;
}
}
sort(pro.begin(),pro.end(),cmp3);
int ans=0;
for(int i=0;i<n;i++){
for(int j=n-1;j>i;j--){
if(pro[j].val<=pro[i].val+1) break;
if(pro[j].a>pro[i].a&&pro[j].d>pro[i].d){
ans++;
break;
}
}

}
return ans;
}
};

2、排序+单调栈
注意攻击相同的 防御从大到小排。

class Solution {
public:
int numberOfWeakCharacters(vector<vector<int>>& properties) {
sort(properties.begin(), properties.end(), cmp);
stack<vector<int>> st;
int n= properties.size();
int ans=0;
for(int i=n-1;i>=0;i--){
while(!st.empty()&&st.top()[1]<=properties[i][1]){
st.pop();
}
if(!st.empty()){
ans++;
}
st.push(properties[i]);
}
return ans;
}
static bool cmp(const vector<int>& x,const vector<int>& y){
return x[0]<y[0] || (x[0]==y[0]&&x[1]>y[1]);
}
};

ps:发现一个问题哈 如果我吧cmp 写成不带const 和 &的会超时

static bool cmp( vector<int> x, vector<int> y){
return x[0]<y[0] || (x[0]==y[0]&&x[1]>y[1]);
}

​3. 访问完所有房间的第一天5​​ 思路:其实有点像 递推那种感觉 ?,就是找 i到i+1 需要多少步数 因为nextvisit[i] 所以 会跑到i前面 因此用个前缀数组 记录一下 可以快速得到区间和 (next[i]数组记录的是 i到i+1需要的步数 pre[i]数组记录的是0-i 需要的步数)

class Solution {
public:
int firstDayBeenInAllRooms(vector<int>& nextVisit) {
int n = nextVisit.size();
if(n==0) return 0;
long long mod = 1e9 + 7 ;
vector<long long> next(n),pre(n); //next[i] = i-->i+1 需要的步数
pre[0] = 2; next[0] = 2;
for(int i=1;i<n-1;i++){
if(i==nextVisit[i]) {
next[i]=2;
pre[i] = (pre[i-1] + 2)%mod;
}
else{
if(nextVisit[i]==0) next[i] = (pre[i-1] +2) % mod;
else next[i] = (pre[i-1] - pre[nextVisit[i]-1] + 2 + mod) %mod;
pre[i] = (pre[i-1] + next[i])%mod;
}
}
return pre[n-2]%mod;
}
};

​4. 数组的最大公因数排序​