E
思维题,不算很直白。
分析:目前到第i个位置我们记录最小和次小的值,用cnt数组记录每个值删掉后会影响多少good数,值得注意的是,对于a如果本身是good数,那么a删掉后至少会影响本身
#include <bits/stdc++.h>
using namespace std;
#define N 1000000+100
int con[N];
int main()
{
// freopen("in.txt","r",stdin);
int t;
for(cin>>t;t;t--)
{
int n;
int fmin=1e9,pmin=1e9;
cin>>n;
for(int i=1,a;i<=n;i++)
{
cin>>a;
if(a<=fmin)
{
pmin=fmin;
fmin=a;
}
else if(a>=fmin&&a<pmin)
{
con[fmin]++;
con[a]++;
pmin=a;
}
else if(a>=pmin)
{
con[a]++;
}
}
int val=con[1];
int it=1;
for(int i=2;i<=n;i++)
{
if(con[i]<val)
{
val=con[i];
it=i;
}
}
cout<<it<<endl;
for(int i=0;i<=n;i++)
{
con[i]=0;
}
}
return 0;
}
G
题目背景是尼姆博弈,添加的理论是从n堆里移除0-d堆的获胜可能情况,先想到的是暴力,发现复杂度不行,转为搜索,发现复杂度还是不行,转为dp
dp状态设计
dp[i][j][k]为前i堆拿走j堆的结果为k的情况
dp[i][j][k]的来源分为两种
1.前i-1堆拿走j-1堆结果为k的情况,
2.前i-1堆拿走j堆结果为k^a[i]的情况
dp[i][j][k]=(dp[i-1][j-1][k]+dp[i-1][j][k^a[i]])
#include <bits/stdc++.h>
using namespace std;
int dp[1030][12][1030];
int a[1000+100];
const int mod=1e9+7;
int main()
{
int t;
for(cin>>t;t;t--)
{
int n,d;
cin>>n>>d;
for(int i=1;i<=n;i++)
cin>>a[i];
memset(dp,0,sizeof(dp));
dp[1][1][0]=1;
dp[1][0][a[1]]=1;
for(int i=2;i<=n;i++)
{
for(int j=0;j<=min(d,i);j++)
{
for(int k=0;k<1024;k++)
{
dp[i][j][k]=(dp[i-1][j-1][k]+dp[i-1][j][k^a[i]])%mod;
}
}
}
int ans=0;
for(int i=0;i<=min(d,n);i++)
{
ans=(ans+dp[n][i][0])%mod;
}
cout<<ans<<endl;
}
return 0;
}