牛客月赛50

目录

减法和求余

生日

工艺品

鸡尾酒数


减法和求余
 

题目描述

鸡尾酒的学生丹丹分不清求余和减法,因为他觉得两种运算都是将一个数字变小,所以都差不多。

为了让丹丹能够更好地理解求余和减法,鸡尾酒给了他这样一个问题:

给定 nnn 个数字,每次有两种操作:

1. 从所有正整数中任选一个数字 x(x>=2)x(x >= 2)x(x>=2),并将所有数字全部对 xxx 求余。
2. 从这 nnn 个数字中任选一些数字,使得它们全部减去一。

问最少进行多少次操作可以让所有数字全部变为 0。

这两种操作都需要“任选”,而丹丹有选择困难症,所以无法解决这一问题,你可以帮帮他吗?

输入描述:

第一行给出一个正整数 n(1≤n≤105)n(1 \leq n \leq 10^5)n(1≤n≤105),表示数字的数量。

接下来给出 nnn 个数字,其中第 iii 个数字记作 ai(0≤ai≤109)a_i(0 \leq a_i \leq 10^9)ai​(0≤ai​≤109)

输出描述:

输出一行一个整数表示答案。

示例1

输入

复制5 1 3 0 12 10

5
1 3 0 12 10

输出

复制2

2

说明

选择x=3,先将所有数字对 3 求余,此时数组变为 [1,0,0,0,1],再选择第一个数字和第五个数字减一,共两次操作可以使得所有数字全部变为 0。

示例2

输入

复制6 5 20 100 15 5 0

6
5 20 100 15 5 0

输出

复制1

1

思路:1.首先根据题意可知,最多需要两次操作。

           2.如果全为0,操作次数0。

           3.如果全为1或者除0以外的其他数共同拥有一个大于1的公因子,操作次数为一。

           4.其他操作次数为2;(先将所有的奇数减一转化为偶数,然后对2取余)。

import java.util.*;
import java.io.*;

public class Main{
	static class FastScanner{
		BufferedReader br;
		StringTokenizer st;
		public FastScanner(InputStream in) {
			br=new BufferedReader( new InputStreamReader(System.in));
			eat("");
		}
		public void eat(String s) {
			st=new StringTokenizer(s);
		}
	
		public String nextLine() {
			try {
				return br.readLine();
			}catch(IOException e) {
				return null;
			}
		}
		
		public boolean hasNext() {
			while(!st.hasMoreTokens()) {
				String s=nextLine();
				if(s==null)return false;
				eat(s);
			}
			
			return true;
		}
		
		public String next() {
			hasNext();
			return st.nextToken();
		}
		
		public int nextInt() {
			return Integer.parseInt(next());
		}
		
		public long nextLong() {
			return Long.parseLong(next());
		}
		
		public double nextDouble() {
			return Double.parseDouble(next());
		}
	}
	
	static FastScanner cin=new FastScanner(System.in);
	static PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
	
	public static void main(String[] args) {
		int n=cin.nextInt();
		int g=0;
		int a=1,b=0;
		
		for(int i=0;i<n;i++) {
			int x=cin.nextInt();
			g=gcd(g,x);//求最大公因数,一个数与0的最大公因数就是该数。
			if(x>1)a=0;
			if(x==0)b++;
		}
		
		if(b==n)out.println(0);
		else if(g>=2||a==1)out.println(1);
		else out.println(2);
		out.flush();
	}

	private static int gcd(int a, int b) {
		// TODO Auto-generated method stub
		if(b==0)return a;
		return gcd(b,a%b);
	}
}

生日

题目描述

共有 nnn 个人,分别编号为 1∼n1 \sim n1∼n,每一个人都有一个属性值,其中第 iii 个人的属性值为 aia_iai​。如果有两个编号为 i,ji,ji,j 的人在同一天过生日,则他们两个人会产生 ai⊕aja_i \oplus a_jai​⊕aj​ 的快乐值,其中 ⊕\oplus⊕ 是位运算中的异或运算符。同理,若三个人或更多人在同一天过生日,则这些人产生的快乐值是所有在这一天过生日的人的异或值。若某一个人单独过生日,则不产生任何快乐值。

为了使得公历生日不同的鸡尾酒和玥玥也可以在同一天过生日,鸡尾酒规定每个人有两个生日,一个公历生日,一个农历生日,且可以在这两天中任选一天进行“过生日”活动。现在我们假设第 iii 个人的公历生日为第 iii 天,农历生日为第 ⌊i2⌋\lfloor \frac{i}{2} \rfloor⌊2i​⌋ 天(其中 ⌊x⌋\lfloor x \rfloor⌊x⌋ 表示对 xxx 向下取整)。那么这 nnn 个人会有很多种不同的过生日方案,现在鸡尾酒想问你所有过生日方案的所有快乐值之和是多少?

两种过生日方案不同当且仅当存在某一个人 iii 在两种方案中选择了不同的一天进行过生日。
由于答案可能很大,请输出答案对 109+710^9+7109+7 取模后的结果。

输入描述:

输入第一行包含一个正整数 n(1≤n≤105)n(1 \leq n \leq 10^5)n(1≤n≤105),表示总人数。

接下来包含 nnn 个数字 ai(0≤ai≤105)a_i(0 \leq a_i \leq 10^5)ai​(0≤ai​≤105),表示每一个人的属性值。

输出描述:

输出一行一个整数表示答案对 109+710^9+7109+7 取模后的结果。

示例1

输入

复制3 1 3 4

3
1 3 4

输出

复制20

20

说明

共有三个人,第 iii 个人的生日是第 iii 天或第 ⌊i2⌋\lfloor \frac{i}{2} \rfloor⌊2i​⌋ 天。即第一个人的生日是第 0/1 天,第二个人的生日是第 1/2 天,第三个人的生日是第 1/3 天
用 [1,2,3] 表示第一个人在第一天过生日,第二个人在第二天过生日,第三个人在第三天过生日。此时没有任何两个人一起过生日,所以快乐值为 0。
[1,1,1] 表示三个人都在第一天过生日,此时产生的快乐值为 6(1、3、4 三个数字的异或值)
[0,1,1] 快乐值为 7。
[1,1,3] 快乐值为 2。
[1,2,1] 快乐值为 5。
其余过生日方案的快乐值都为 0,因为这些方案中没有任何两个人在同一天过生日。
求和得到 20。

示例2

输入

复制4 1 2 3 4

4
1 2 3 4

输出

复制36

36

说明

[1,2,1,2] 表示第一个人和第三个人在第一天过生日,产生的快乐值为 1⊕3=21 \oplus 3=21⊕3=2;第二个和第四个人都在第二天过生日,产生的快乐值为 2⊕4=62 \oplus 4=62⊕4=6,所以这一种方案共产生快乐值为 6 + 2 = 8。
[1,2,3,2]、[0,2,3,2]、[0,2,1,2] 这三种方案都只有第二个和第四个人一起过生日,产生快乐值都为 6,三种方案快乐值共计 6*3=18。
[1,2,1,4] 产生快乐值为 2。
[1,1,1,4]、[1,1,1,2] 这两种方案是前三个人一起过生日,但是 1⊕2⊕3=01 \oplus 2 \oplus 3 = 01⊕2⊕3=0,所以这三种方案产生的快乐值为 0。
[0,1,1,4]、[0,1,1,2] 的快乐值均为 1,两种方案共计 2*1=2。
[1,1,3,4]、[1,1,3,2] 的快乐值均为 3,两种方案共计 3*2=6。
其余方案的快乐值为 0,以上所有方案快乐值之和为 8+18+2+2+6=36

思路:假设三个人可以选择在同一天过生日,那么,三个人之间的组合是任意的,可以任意选择,找出其贡献即可,而剩下的(n-3)个人同样可以任意选择,有2^(n-3)种可能,所以该种结果的贡献值为(ai^a2*i^a(2*i+1)+ai^a2*i+ai^a(2*i+1)+a(2*i+1)^a2*i)*2^(n-3)。两个人可以同时过生日的同理。

import java.util.*;
import java.io.*;

public class Main{
	static class FastScanner{
		BufferedReader br;
		StringTokenizer st;
		public FastScanner(InputStream in) {
			br=new BufferedReader( new InputStreamReader(System.in));
			eat("");
		}
		public void eat(String s) {
			st=new StringTokenizer(s);
		}
	
		public String nextLine() {
			try {
				return br.readLine();
			}catch(IOException e) {
				return null;
			}
		}
		
		public boolean hasNext() {
			while(!st.hasMoreTokens()) {
				String s=nextLine();
				if(s==null)return false;
				eat(s);
			}
			
			return true;
		}
		
		public String next() {
			hasNext();
			return st.nextToken();
		}
		
		public int nextInt() {
			return Integer.parseInt(next());
		}
		
		public long nextLong() {
			return Long.parseLong(next());
		}
		
		public double nextDouble() {
			return Double.parseDouble(next());
		}
	}
	
	static FastScanner cin=new FastScanner(System.in);
	static PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
	
	static int mod=(int) (1e9+7);
	public static void main(String[] args) {
		int n=cin.nextInt();
		int a[]=new int[n+1];
		
		for(int i=1;i<=n;i++) {
			a[i]=cin.nextInt();
		}
		
		long ans=0;
		for(int i=1;i<=n;i++) {
			int t=i*2;
			if(t>n)break;
			else if(t==n) {
				ans=(ans+qmi(2,n-2)*(a[i]^a[t])%mod)%mod;
			}else {
				int sum=(a[i]^a[t]^a[t+1])+(a[i]^a[t])+(a[i]^a[t+1])+(a[t]^a[t+1]);
				ans=(ans+qmi(2,n-3)*(sum)%mod)%mod;
			}
			
		}
		
		out.println(ans);
		out.flush();
	}

	private static long qmi(long a, long b) {
		// TODO Auto-generated method stub
		long res=1;
		while(b>0) {
			if(b%2==1)res=(res*a)%mod;
			b/=2;
			a=a*a%mod;
		}
		return res%mod;
	}
}

工艺品

题目描述

鸡尾酒和玥玥一起加工工艺品。鸡尾酒花费连续的 aaa 分钟可以加工出一个成品,玥玥每 bbb 分钟可以加工出一个半成品,然后需要交给鸡尾酒花费连续的 ccc 分钟将半成品加工为成品。

花费连续的 aaa 分钟指的是在这 aaa 分钟内不能做其他事,也不能中断。

现在总共有 nnn 分钟,问他们两人最多能够加工出多少件成品。(两人可以同时开始加工)

输入描述:

输入仅包含一行,共四个正整数 n,a,b,c(1≤a,b,c≤n≤109)n,a,b,c(1 \leq a,b,c \leq n \leq 10^9)n,a,b,c(1≤a,b,c≤n≤109)

输出描述:

输出一行一个整数表示答案。

示例1

输入

复制10 1 2 3

10 1 2 3

输出

复制10

10

说明

鸡尾酒独自加工即可,因为加工一件半成品的时间比独自加工的时间长。

示例2

输入

复制10 5 3 2

10 5 3 2

输出

复制3

3

说明

鸡尾酒先独自加工一件产品,消耗 5 分钟。此时玥玥已经花 3 分钟加工了一件半成品,此时鸡尾酒花费 2 分钟完成这件半成品的加工,共消耗 7 分钟。而此时玥玥又会加工好一件半成品,则鸡尾酒继续加工半成品,共加工 3 件工艺品。

思路:1.a<=c:鸡尾酒一直在加工

           2.a>c:尽可能多的加工玥玥加工的半成品。

                cnt=(n-c)/max(b,c);//能够加工的半成品,n-c是最后预留的加工最后一个半成品的时间。

                (n-cnt*c)/a//能够加工的成品

import java.util.*;
import java.io.*;

public class Main{
	static class FastScanner{
		BufferedReader br;
		StringTokenizer st;
		public FastScanner(InputStream in) {
			br=new BufferedReader( new InputStreamReader(System.in));
			eat("");
		}
		public void eat(String s) {
			st=new StringTokenizer(s);
		}
	
		public String nextLine() {
			try {
				return br.readLine();
			}catch(IOException e) {
				return null;
			}
		}
		
		public boolean hasNext() {
			while(!st.hasMoreTokens()) {
				String s=nextLine();
				if(s==null)return false;
				eat(s);
			}
			
			return true;
		}
		
		public String next() {
			hasNext();
			return st.nextToken();
		}
		
		public int nextInt() {
			return Integer.parseInt(next());
		}
		
		public long nextLong() {
			return Long.parseLong(next());
		}
		
		public double nextDouble() {
			return Double.parseDouble(next());
		}
	}
	
	static FastScanner cin=new FastScanner(System.in);
	static PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

	public static void main(String[] args) {
		int n=cin.nextInt();
		int a=cin.nextInt(),b=cin.nextInt(),c=cin.nextInt();
		
		if(a<=c) {	
            out.println(n/a);
			out.flush();
		}else {
			int cnt=(n-c)/Math.max(c, b);
			int ans=(n-cnt*c)/a+cnt;
            out.println(ans);
			out.flush();
		}
	}
}

鸡尾酒数

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

定义数位和是一个数字中每一个数位的和,例如数字 123 的数位和是 1+2+3=6,数字 1024 的数位和是 1+0+2+4=7。

鸡尾酒和玥玥的生日连起来是 512417,这个数字的数位和是 5+1+2+4+1+7=20,恰好是 10 的倍数。所以鸡尾酒定义:如果某一个数字的数位和恰好是 10 的倍数,那么我们称它为一个“鸡尾酒数”。

给定 nnn,请问 1∼n1\sim n1∼n (即 111 到 nnn 之间所有整数)这些数字中有多少个鸡尾酒数,由于结果可能很大,请输出答案对 109+710^9+7109+7 取模后的结果。

题目出到这里,鸡尾酒深感这样的难度远远无法满足参与小白玥赛的众位小白之王,于是加入了单点修改的机制。再给定 qqq 次询问,每次询问给出两个数字 a,ba,ba,b,表示将 nnn 的数位中从左往右的第 aaa 位修改为数字 bbb,再问 1∼n1 \sim n1∼n 中有多少个鸡尾酒数。对于每次询问你都需要回答一次这个问题。

请注意:每次询问时的修改都会永久生效;一个数字最左边的一位记为第一位。

输入描述:

输入一行包含一个整数 n(1≤n≤10100000)n(1 \leq n \leq 10^{100000})n(1≤n≤10100000) 和一个正整数 q(0≤q≤105)q(0 \leq q \leq 10^5)q(0≤q≤105),其中 qqq 表示询问的次数。

接下来包含 qqq 行,每行给出两个整数 a,b(1≤a≤len,0≤b≤9)a,b(1 \leq a \leq len, 0 \leq b \leq 9)a,b(1≤a≤len,0≤b≤9),保证修改之后的数字不包含前导零,其中 lenlenlen 为数字 nnn 的长度。

输出描述:

输出 q+1q+1q+1 行,第一行的数字表示答案对 109+710^9+7109+7 取模后的结果。

之后对于每一次询问给出一个回答,同样输出答案对 109+710^9+7109+7 取模之后的结果。

示例1

输入

复制1 0

1 0

输出

复制0

0

说明

样例在询问 1 到 1 之间有多少个鸡尾酒数。1 的数位和是 1,不是 10 的倍数,所以没有鸡尾酒数。此样例没有修改的操作,所以只需输出一行。

示例2

输入

复制102 2 3 9 2 1

102 2
3 9
2 1

输出

复制9 10 11

9
10
11

说明

首先输出 9 表示 1∼1021 \sim 1021∼102 中有 9 个鸡尾酒数;第一次修改将第三个位置改为 9,此时 nnn 变为 109,输出 10 表示 1∼1091 \sim 1091∼109 中有 10 个鸡尾酒数。第二次修改在之前的基础上将第二个位置改为 1,即 nnn 被修改为 119,此时输出 11 表示 1∼1191 \sim 1191∼119 中有 11 个鸡尾酒数。

思路:根据题意我们可以的到,1~n的鸡尾酒数为(n/10),如果(10-sum%10)%10>c[c.length-1]-'0',需要将答案减一。

        求一个数对另一个数取余的余数:例如:999 %10为(900%10+90%10+9%10)%10;

import java.util.*;
import java.io.*;
import java.math.BigInteger;

public class Main{
	static class FastScanner{
		BufferedReader br;
		StringTokenizer st;
		public FastScanner(InputStream in) {
			br=new BufferedReader( new InputStreamReader(System.in));
			eat("");
		}
		public void eat(String s) {
			st=new StringTokenizer(s);
		}
	
		public String nextLine() {
			try {
				return br.readLine();
			}catch(IOException e) {
				return null;
			}
		}
		
		public boolean hasNext() {
			while(!st.hasMoreTokens()) {
				String s=nextLine();
				if(s==null)return false;
				eat(s);
			}
			
			return true;
		}
		
		public String next() {
			hasNext();
			return st.nextToken();
		}
		
		public int nextInt() {
			return Integer.parseInt(next());
		}
		
		public long nextLong() {
			return Long.parseLong(next());
		}
		
		public double nextDouble() {
			return Double.parseDouble(next());
		}
	}
	
	static FastScanner cin=new FastScanner(System.in);
	static PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

	static long mod=(long) (1e9+7);
	public static void main(String[] args) {
		String s=" "+cin.next();
		int q=cin.nextInt();
		if(s.length()==2) {
			for(int i=0;i<=q;i++) {
				out.println(0);
				out.flush();
			}
		}
		else {
			char c[]=s.toCharArray();
			long p[]=new long[100010];
			long sum=0,ans=0;
			p[0]=1;
			
			for(int i=1;i<c.length-1;i++) {
				p[i]=p[i-1]*10%mod;
				sum+=c[i]-'0';
				ans=(ans*10+(c[i]-'0'))%mod;
			}
			
			if((10-sum%10)%10>c[c.length-1]-'0') {
				long t=(ans-1+mod)%mod;
				out.println(t);
				out.flush();
			}else {
				out.println(ans);
				out.flush();
			}
			
			while(q-->0) {
				int a=cin.nextInt(),b=cin.nextInt();
				
				if(a!=c.length-1) {
					sum+=b-(c[a]-'0');
					int w=c.length-a-1;
					ans=(ans-(c[a]-'0')*p[w-1]%mod+b*p[w-1]%mod+mod)%mod;
				}
				
				c[a]=(char) (b+'0');
				
				if((10-sum%10)%10>c[c.length-1]-'0') {
					long t=(ans-1+mod)%mod;
					out.println(t);
					out.flush();
				}else out.println(ans);
				
				out.flush();
			}
			
		}

		out.flush();
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值