小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)); } }以上代码,运行时间为2ms
import 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整除即可。