20200508

C题.[Codeforces 831C] Jury Marks //暴力枚举

题目连接

思路

复杂版:
b[1]肯定是要放入某个位置的,放到某个位置之后,按照a数组的特定顺序分别向前逆打分向后正打分,就会得到特定的按照a数组打每个分后应该公布的每个分值(设其为数组B),这时候如果b数组中的每个值在B数组中都存在,我们前面放置b[1]的这种方案就合法,这时向前逆打分过程中求出来的最初分值就是一个合法的最初分值
(逆打分的意思就是还原打分前的情况,即依次-a[i]。正打分就是继续打分,即依次+a[i])
所以做法就是枚举b[1]可以放的位置(1->k),然后从这个位置分别向前逆打分、向后正打分,判断按这个方案得到的B数组里是否包含b数组中所有数,如果是,就合法,如果合法且向前得到的最初分值没出现过,答案就+1

简洁版:
枚举放置b[1]的位置(1->k),向前向后模拟打分过程,从而推出b数组应有的(1->k)全貌,判断b数组中每个数是否都有出现,若是则合法,累计(注意对最初分值去重)。

//AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=2007,M=8000000;
int k,n,a[N],b[N],ans;
bool f[2*M+7];
map<int,int>mp;
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>k>>n;
	for(int i=1;i<=k;i++)cin>>a[i];
	for(int i=1;i<=n;i++)cin>>b[i],f[M+b[i]]=1;
	int pre,nxt,flag;
	for(int i=1;i<=k;i++){
		nxt=pre=b[1];flag=1;
		f[M+b[1]]=0;
		for(int j=i;j>1;j--){
			pre-=a[j];
			f[M+pre]=0;
		}
		pre-=a[1];
		for(int j=i+1;j<=k;j++){
			nxt+=a[j];
			f[M+nxt]=0;
		}
		for(int j=1;j<=n;j++){
			if(f[M+b[j]])flag=0;
			f[M+b[j]]=1;
		}
		if(flag&&mp.count(pre)==0){
			ans++;
			mp[pre]=1;
		}
	}
	cout<<ans;
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linkscx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值