题解看不懂
做法是暴力枚举
#include<iostream>
#include<string>
using namespace std;
int n,m,z[1000];
string f;
int num1(){//记录有几条自己中招
int ans=0;
for(int i=0;i<n;i++)
if(f[z[i]-1]=='1')ans++;
return ans;
}
void willkill(int a,int &much,int &xb_much){
//当删第a条之后会有几条中招,记录在much下标在xb_much
int killedz[1000],ans=0;
for(int i=0;i<n;i++)killedz[i]=z[i];//传输变量到另一个列表
for(int i=0;i<n;i++){
if(killedz[i]>a&&killedz[i]!=-1)killedz[i]--;
//大于被删除项则序号-1,小于则不变
if(killedz[i]==a&&killedz[i]!=-1)killedz[i]==-1;
//如果删自己的将自己消息列表中那项设为无效(-1)
}
for(int i=0;i<n;i++)//记录自己有几条中招
if(f[killedz[i]-1]=='1')ans++;
much=ans,xb_much=a;//相当于返回两个值
}
void killed(int a){
//删除第a项后自己消息序列发生的改变
for(int i=0;i<n;i++){
if(z[i]>a&&z[i]!=1)z[i]--;
if(z[i]==a&&z[i]!=1)z[i]=-1;
//参见函数"willkill"
}
}
int main(){
int min=999,much,xb_much,xb_min,ans=0;
cin>>n>>m>>f;//n是自己,m是全部,f是函数01字符串
for(int i=0;i<n;i++)cin>>z[i];
while(num1()!=0){//当自己要惩罚的数量>0循环
for(int i=0;i<m;i++){//把当前所有条依次删过去过去
willkill(i,much,xb_much);//传输删除i时中招个数
if(min>much)min=much,xb_min=xb_much;//记录中招小值&下标
}
killed(xb_min);//删除自己招个数最小值的下标
ans++;//记录次数;
}
cout<<ans;//输出次数
return 0;
}