zhw神犇出题就是强啊。。。
A:pairs
John 在
X
轴上拥有
题解
对于每个点,二分它右边离他最远、但是又在距离
k
内的点,然后加到答案里,这样做复杂度是
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 110000
using namespace std;
typedef long long int LL;
LL ans=0;
int x[MAXN],n,k;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ans=0;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&x[i]);
sort(x+1,x+n+1);
for(int i=1;i<=n;i++)
{
int lowerBound=i,upperBound=n;
int tmp;
while(lowerBound<=upperBound)
{
int mid=(lowerBound+upperBound)>>1;
if(x[mid]-x[i]>k) upperBound=mid-1;
else tmp=mid,lowerBound=mid+1;
}
ans+=(LL)(tmp-i);
}
printf("%lld\n",ans);
}
return 0;
}
B:beautiful number
令
A=∑ni=1ai∗10n−i(1≤ai≤9)
(
n
为
题解
此题做法很多,可以暴力从1枚举到1e9,然后打表记下来,也可以记录下前面一位数字往后面一位数字如何转移,然后做一个DFS的预处理,也可以直接用DFS在线回答询问
我的方法是最后一种,代码比较直白,就不需要过多解释了吧
坑爹的是此题pretest依然很水,然后我保存数字每个数位的digit数组只开了10位,但是如果到极限数据(1e9)时就需要11位,然后导致我最终fst了,坑爹啊!!!!(zhw的pretest实在太神奇了)
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
int digit[11],len; //digit数组保存数位(个位在1),len数组保存x的长度,digit数组刚开始我开成10然后过了pretest最终fst有木有!!!!掉rating有木有!!!!!
int num[10][11]={
{10,0,1,2,3,4,5,6,7,8,9},
{1,1,0,0,0,0,0,0,0,0,0},
{2,2,1,0,0,0,0,0,0,0,0},
{2,3,1,0,0,0,0,0,0,0,0},
{3,4,2,1,0,0,0,0,0,0,0},
{2,5,1,0,0,0,0,0,0,0,0},
{4,6,3,2,1,0,0,0,0,0,0},
{2,7,1,0,0,0,0,0,0,0,0},
{4,8,4,2,1,0,0,0,0,0,0},
{3,9,3,1,0,0,0,0,0,0,0}
};
int ans=0;
void DFS(int last,int pos,bool danger)
{
if(pos==0)
{
ans++;
return;
}
for(int i=1;i<=num[last][0];i++)
{
int next=num[last][i]; //下一个填入的数字是next
if(!danger)
{
if(next!=0&&last!=0)
DFS(next,pos-1,false);
else if(!last)
DFS(next,pos-1,false);
}
else if(last==digit[pos+1]&&digit[pos]>=next)
{
if(digit[pos]==next)
DFS(next,pos-1,true);
else
DFS(next,pos-1,false);
}
}
}
int work(int x) //求[1,x]中美丽的数的个数
{
if(!x) return 1;
ans=0;
len=0;
while(x)
{
digit[++len]=x%10;
x/=10;
}
for(int i=0;i<=9;i++)
if(digit[len]>=i)
{
if(digit[len]==i)
DFS(i,len-1,true);
else
DFS(i,len-1,false);
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int L,R;
scanf("%d%d",&L,&R);
printf("%d\n",work(R)-work(L-1));
}
return 0;
}
C:chess
在n∗n的国际象棋中,放置若干个国王和k个车,使得国王之间不互相攻击,车之间不互相攻击,车不可攻击到国王(这并不代表国王不能攻击到车)。国王能攻击到它上下左右,左上左下右上右下八个位置的棋子,车可以攻击到同一行或同一列中的棋子,求方案总数对1000000007取模后的值。
D:numbers
现在你有一个栈和
n
个数
这个问题非常简单,因此我想给你一些限制条件。
这里有
你能告诉我有多少种合法的弹出栈的方案吗?
我知道这个答案或许非常大,你只需告诉我这个答案
mod1000000007(109+7)
就行了。