zhw神犇出题就是强啊。。。
John 在 X 轴上拥有 n 个点,他们的坐标分别为 (x[i],0) , (i=0,1,2,…,n−1) 。 他想知道有多少对 <a,b> 满足 |x[b]−x[a]|≤k(a<b) 。
题解
对于每个点,二分它右边离他最远、但是又在距离 k 内的点,然后加到答案里,这样做复杂度是 nlogn 的,由于pretest太水,最终AC的人竟然并不是很多
#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;
}
令 A=∑ni=1ai∗10n−i(1≤ai≤9) ( n 为 A 的位数)。若 A 为“漂亮的数”当且仅当对于任意 1≤i<n 满足 a[i]≥a[i+1] 且对于任意 1≤i≤n,i<j≤n ,满足 a[i] mod a[j]=0 (例如931是一个“漂亮的数”而87不是),求在区间 [L,R] (包含L和R)里“漂亮的数”的个数。
题解
此题做法很多,可以暴力从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;
}
在n∗n的国际象棋中,放置若干个国王和k个车,使得国王之间不互相攻击,车之间不互相攻击,车不可攻击到国王(这并不代表国王不能攻击到车)。国王能攻击到它上下左右,左上左下右上右下八个位置的棋子,车可以攻击到同一行或同一列中的棋子,求方案总数对1000000007取模后的值。
现在你有一个栈和 n 个数 1,2,3,…,n 。这 n 个数依次进入栈顶,且在某个时刻在栈顶中弹出。你可以参见样例获得更多的信息。
这个问题非常简单,因此我想给你一些限制条件。
这里有 m 个限制,每个限制形如 <A,B> ,表示 A 必须在 B 之前先弹出。
你能告诉我有多少种合法的弹出栈的方案吗?
我知道这个答案或许非常大,你只需告诉我这个答案 mod1000000007(109+7) 就行了。