小Q得到一个神奇的数列: 1, 12, 123,...12345678910,1234567891011...。
并且小Q对于能否被3整除这个性质很感兴趣。
小Q现在希望你能帮他计算一下从数列的第l个到第r个(包含端点)有多少个数可以被3整除。
小Q得到一个神奇的数列: 1, 12, 123,...12345678910,1234567891011...。
并且小Q对于能否被3整除这个性质很感兴趣。
小Q现在希望你能帮他计算一下从数列的第l个到第r个(包含端点)有多少个数可以被3整除。
输入包括两个整数l和r(1 <= l <= r <= 1e9), 表示要求解的区间两端。
输出一个整数, 表示区间内能被3整除的数字个数。
2 5
3
12, 123, 1234, 12345...
其中12, 123, 12345能被3整除。
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
int main(){
ll l , r;
while(cin >> l >> r){
ll count = 0;
for(int i = l; i <= r; i++){
if((i+1)*i/2 % 3 == 0) count++;
}
cout << count << endl;
}
return 0;
} #include <iostream>
using namespace std;
int main(void){
int i, j;
int count = 0;
cin>>i>>j;
for(int k = i; k <= j; k++){
if(k % 3 != 1)
count++;
}
cout<<count;
return 0;
} 能被3整除的数的特征:各个数位上数字之和能被3整除推广:不是一个数字一个数字地拆分,把某个数视为字符串划分为多个任意长度的数字字符串,比如a=137928672拆成b=137,c=9286,d=72,那么有a%3=(b+c+d)%3
import sys a = sys.stdin.readline().strip().split() ans = 0 i = int(a[0]) j = int(a[1]) total1 = (1 + i)*i//2 total2 = (2 + i)*(i+1)//2 total3 = (3 + i)*(i+2)//2 mod = [total1%3, total2%3, total3%3] ans += 2*((j-i+1)//3) ansmod = (j-i+1)%3 ans += mod[:ansmod].count(0) print(ans)
发现:第i个数为123...i, 则第L个数为123...L,能被3整除的数有一个性质,即各个位加和能 被3整除,例如:若第L个数能被3整除即: 123...L能被3整除则(1+2+3+ ...+L)能被3整除import java.util.*;
#include<stdio.h>
int main()
{
int l,r,i,j;
while(~scanf("%d %d",&l,&r))
{
i=(r-l)/3;
j=(r-l)%3;
if(j==0)
j=i;
else
j=i+j;
printf("%d\n",j);
}
}
自己列举可以发现规律,给定一个数X,X/3即为1——X的能被3整除的个数,但是这是在默认1起步的情况下。当起始点发生变化,我们就需要考虑到余数。假定(L-R)/3为正确的个数,事实并非如此,通过找规律可发现(L-R)%3一直在0,1,2之间连续变动,且为1,2时正解应该为(L-R)/3+1。
#include<stdio.h>
#define func(x) (((x)/3)*2+(((x)%3==2)?1:0)) /*func(x)表示正整数1~x中除3余数不为1的数的个数*/
int main()
{
int l,r;
while(~scanf("%d %d",&l,&r))
{
printf("%d\n",func(r)-func(l-1));
}
} 以上代码,运行时间为2msimport java.util.Scanner;
public class Main {
public static int sum(int i){
return i/3*2+(i%3==2?1:0);
}
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int l = input.nextInt();
int r = input.nextInt();
System.out.println(sum(r) - sum(l-1));
}
}
```思路常规比较容易想到 没有高赞的精妙
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int a,b,cnt=0;
long long sum=0;
while(cin>>a>>b)
{
if(a>b) return -1;
for(int i=1;i<=a;i++)
sum+=i;
for(int i=a+1;i<=b+1;sum+=i,i++)
if(sum%3==0) cnt++;
}
cout<<cnt<<endl;
return 0;
}```
""" 从l到n遍历: 可以被3整除的数 加上 余1的数 余1 余1的数 加上 余2的数 可以被3整除 可以被3整除的数 加上 余0的数 也可以被3整除 3个为一组,后两个可以被整除 """ def cnt_mod_3(n): return (n // 3) * 2 + max(0, n % 3 - 1) if __name__ == "__main__": l, r = list(map(int, input().strip().split())) print(cnt_mod_3(r) - cnt_mod_3(l - 1))
import sys l,r=map(int,sys.stdin.readline().split()) def getnum(integer): if integer-integer//3*3==2: s=1 else: s=0 return integer//3*2+s print(getnum(r)-getnum(l-1))
本套8道题全部pass的C++代码已挂到了我的GitHub(https://github.com/shiqitao/NowCoder-Solutions)
牛客网上的其他题目解答也在持续更新。
#include <iostream>
using namespace std;
int main()
{
int l, r; cin >> l >> r;
int count = (r - l + 1) / 3 * 2;
int num = r - l + 1 - (r - l + 1) / 3 * 3;
if (num == 1 && (l % 3 == 0 || l % 3 == 2)) {
count += 1;
}
else if (num == 2 && (l % 3 == 0 || l % 3 == 1)) {
count += 1;
}
else if (num == 2 && l % 3 == 2) {
count += 2;
}
cout << count;
return 0;
}
#include<iostream>
using namespace std;
typedef long long ll;
ll getSum(ll num){
ll tmp = 0;
for(ll i=1; i<=num; i++){
tmp += i;
}
return tmp;
}
int main(){
ll l,r;
while(cin >> l >> r){
ll cnt = 0;
ll tmp = getSum(l);
for(ll i=l; i<=r; i++){
if(tmp % 3==0) cnt++;
tmp += i+1;
}
cout << cnt <<endl;
}
}
# 受到 lslotus 找规律的启发,写出了下面的程序 import sys import sys a = sys.stdin.readline().strip().split() l, r = map(int, a) def solution(l, r): ans = (r - l + 1) // 3 * 2 for i in range(l, l + (r - l + 1) % 3): if i % 3 == 1: continue else: ans += 1 return ans if __name__ == '__main__': print(solution(l, r))
if( ( i % 3 )% 2 == 0) count ++;我来解释下为什么用序号%3%2就可以判断。
#include <iostream>
(720)#include<cmath>
using namespace std;
int main()
{
long int r_st, r_end;
cin >> r_st >> r_end;
int count = 0;
if (r_st < 1 || r_end > pow(10, 9) || r_st >= r_end)
{
cout << "数值超过限制或输入有误!!!";
exit(1);
}
for (int i = r_st; i <= r_end; i++)
{
if ((i % 3) == 0)
{
count++;
}
}
cout << count << endl;
return 0;
} import java.util.Scanner;
import java.lang.*;
public class Main {
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int x=sc.nextInt();
int y=sc.nextInt();
int count=0;
for(int i=x;i<=y;i++){
int tempNum=0;
for(int k=1;k<=i;k++){
int wei=Num2(k,i);
tempNum+=k*Math.pow(10,wei);
}
if(tempNum%3==0){
count++;
}
}
System.out.println(count);
}
}
public static int Num2(int start,int end){
int num=0;
for(int j=start+1;j<=end;j++){
String tempStr=Integer.toString(j);
num+=tempStr.length();
}
return num;
}
}
一种不找规律,直接求解的笨方法,以1234数字为例:1234=1*10^3+2*10^2+3*10+4,每个数字都可以这样得到计算,然后看是否能被3整除即可。