1.游戏(单调队列)


注意如果结果是分数,直接设置变量为double,最好不要使用把int类型乘1.0变成分数来计算。
#include <iostream>
#include <queue>
using namespace std;
const int N=1e5+10;
//滑动窗口大小为k,最大值为P,最小值为Q,K=P-Q
//窗口个数为cnt=n-k+1
//所有情况为all=cnt*cnt
//期望值为(K1+K2+...+Kall)/all
//由于熊大选框和熊二选框的情况是一样的,因此只需要
//(K1+K2+...+Kcnt)/cnt
int a[N];
int wd[N];
deque<int>q;//双端队列
int main()
{
int n,k;
scanf("%d %d\n",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
double sump=0;//窗口最大值加和
for(int i=1;i<=n;i++)
{
while(!q.empty()&&a[q.back()]<a[i])q.pop_back();
q.push_back(i);//4 3 2 1...(从大到小的窗口)a[i]<=a[q.back()]才加入
if(i>=k)//大于等于窗口大小才开始计算答案
{ //不在窗口内的下标pop掉
while(!q.empty()&&q.front()<=i-k)q.pop_front();
sump+=a[q.front()];
}
}
q.clear();//注意要把队列清空!
double sumq=0;//窗口最小值加和
for(int i=1;i<=n;i++)
{
while(!q.empty()&&a[q.back()]>a[i])q.pop_back();
q.push_back(i);//1 2 3 4...(从小到大的窗口)a[i]>=a[q.back()]才加入
if(i>=k)//大于等于窗口大小才开始计算答案
{ //不在窗口内的下标pop掉
while(!q.empty()&&q.front()<=i-k)q.pop_front();
sumq+=a[q.front()];
}
}
printf("%.2lf\n",(sump-sumq)/(n-k+1));
return 0;
}
2.01游戏(DFS剪枝)


#include<iostream>
using namespace std;
char a[15][15];
bool flag=0;
int n;
bool check()
{
//判断行
for(int i=0;i<n;i++)
{
int cnt0=0,cnt1=0;//记录连续出现
int sum0=0,sum1=0;
for(int j=0;j<n;j++)
{
if(a[i][j]=='_')cnt1=0,cnt0=0;//连续中断
else if(a[i][j]=='1'){
cnt1++;
sum1++;
cnt0=0;
}else if(a[i][j]=='0'){
cnt0++;
sum0++;
cnt1=0;
}
if(cnt1>2||cnt0>2)return 0;
if(sum1>n/2||sum0>n/2) return false;//超过一半就无法保证数量相等
}
}
//判断列
for(int i=0;i<n;i++)
{
int cnt0=0,cnt1=0;//记录连续出现
int sum0=0,sum1=0;
for(int j=0;j<n;j++)
{
if(a[j][i]=='_')cnt1=0,cnt0=0;//连续中断
else if(a[j][i]=='1'){
cnt1++;
sum1++;
cnt0=0;
}else if(a[j][i]=='0'){
cnt0++;
sum0++;
cnt1=0;
}
if(cnt1>2||cnt0>2)return 0;
if(sum1>n/2||sum0>n/2) return false;//超过一半就无法保证数量相等
}
}
return 1;
}
void dfs(int x,int y)//默认是先向右走再向下走
{
if(flag)return;
if(y==n)
{
x++;//再向下
y=0;//再从左边起始开始
}
if(x==n)
{
//到达右下角了可以输出答案
flag=1;
for(int i=0;i<

最低0.47元/天 解锁文章
1666

被折叠的 条评论
为什么被折叠?



