题目链接
知识一览
01 - 二进制1/0个数(B题)
02 - 差分+贪心(F题)
题目列表
快输
static class FastReader{
BufferedReader br;
StringTokenizer st;
String tmp;
public FastReader() {
br=new BufferedReader(new InputStreamReader(System.in));
}
String next() {
while(st==null||!st.hasMoreElements()) {
try {
st=new StringTokenizer(br.readLine());
}catch(IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong(){return Long.parseLong(next());}
String nextLine() {
String str="";
try {
str=br.readLine();
}catch(IOException e) {
e.printStackTrace();
}
return str;
}
boolean hasNext(){
if(st!=null&&st.hasMoreTokens())return true;
try {
tmp=br.readLine();
st=new StringTokenizer(tmp);
}catch(IOException e) {
return false;
}
return true;
}
}
static PrintWriter out=new PrintWriter(
new BufferedWriter(new OutputStreamWriter(System.out)));
static FastReader sc=new FastReader();
B - match
①现在有一个关于数字匹配的概念:对于两个正整数x,y,把x,y分别转换成二进制数,并将它们非前导零的部分取出当做一个字符串,把这两个字符串连起来形成一个新的字符串,如果新字符串中0的个数和1的个数之差的绝对值恰好为1,则认为这两个数字是匹配的。
②求对于a[1]-a[n],请问a[i]与a[j](1<=i<j<=n)匹配的概率是多少,把答案对于1e9+7进行取模。
③取模运算前的结果为最简分数吗,注意用快速幂求逆元。
static int mod=(int)1e9+7;
static Map<Integer,Integer> mp;
public static void main(String[] args) {
int T=sc.nextInt();
//int T=1;
while(T-->0){
solve();
}
}
private static void solve(){
int n=sc.nextInt();
mp=new HashMap<>();
long sum=0;
for(int i=1;i<=n;i++){
int x=sc.nextInt();
x=f(x);
sum+=mp.getOrDefault(-x-1,0)+mp.getOrDefault(-x+1,0);
mp.put(x,mp.getOrDefault(x,0)+1);
}
long t=(long)n*(n-1)/2;
out.println(sum*ksm(t,mod-2,mod)%mod);
out.flush();
}
private static int f(int a){
int sum=0;
while(a>0){
sum+=(a&1)==1?1:-1;
a>>=1;
}
return sum;
}
private static long ksm(long a,long b,long p){
//a本身可能超出mod范围
long res=1;a=a%p;
while(b>0){
if((b&1)==1)res=res*a%p;
a=a*a%p;
b>>=1;
}
return res;
}
F candy-hard(差分+贪心)
现在班上有n个同学,第i个同学的表现应该被奖励至少a[i]颗糖果,而llz老师拥有m种口味的糖果,第i种口味的糖果共有b[i]颗。如果一个小朋友被奖励的糖果都是不同口味的(即没有重复的口味),那么他就会很高兴。现在llz想知道是否存在一种分配方式,使得每个小朋友都能开心快乐。
数据范围较大,不能用暴力模拟
static int maxn=(int)5e4+5;
static int a[],sum[];
static int n,m;
public static void main(String[] args) {
int T=sc.nextInt();
//int T=1;
while(T-->0){
solve();
}
}
private static void solve(){
sum=new int[maxn];
n=sc.nextInt();
m=sc.nextInt();
a=new int[n+1];
for(int i=1;i<=n;i++)a[i]=sc.nextInt();
int mx=0;
for(int i=1;i<=m;i++){
int x=sc.nextInt();
mx=Math.max(mx,x);
sum[1]++;sum[1+x]--;//差分数组 区间1-b[i] +1
}
boolean f=true;
Arrays.sort(a);
/*前缀和数组
假设每次都将每种糖果各取其一,若没有这种糖果则不取
sum[i] : 第 i 次能取的最大糖果数
*/
for(int i=1;i<=mx+1;i++) {
sum[i]+=sum[i-1];
}
int idx;
for(int i=1;i<=n;i++){
//数组a降序 :从大到小
idx=n+1-i;
if(a[idx]>sum[i]){
f=false;
break;
}
else sum[i+1]+=sum[i]-a[idx];
}
if(f)out.println("yes");
else out.println("no");
out.flush();
}