【牛客 - 318L】彪神666(水题,半高精度,递推,trick)

题干:
 

在国外,666代表魔鬼,777代表上帝。

所以牛逼的彪神就非常不喜欢6这个数字。

有一天彪神突发奇想,,他想求一些书与6无关的数。

如果一个数能被6整除,或者它的十进制表示法中某位上的数字为6,则称其为与6相关的数。彪神要求所有小于等于N的与6无关的正整数的平方和。

输入描述:

 

第一行一个数T表示有T组数据。(T≤20)

后面T行数每行一个N,表示求所有小于等于N的与6无关的正整数的平方和。(N≤106)

输出描述:

T行,每行一个数表示求所有小于等于N的与6无关的正整数的平方和。

示例1

输入

复制

5
4
5
6
7
8

输出

复制

30
55
55
104
168

解题报告:

     水题,打表递推一下就可以了。。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e6 + 5;
ll mod = 1e13;
ll b[MAX],bb[MAX];
int a[55];
int cf(int x) {
    int p = 0;
    while(x) {
        a[++p] = x%10;
        x/=10;
    }
    return p;
}
int main()
{
    for(ll i = 1; i<=(int)1e6; i++) {
        b[i]=b[i-1];
        bb[i]=bb[i-1];
        int p = cf(i),flag = 1;
        for(int j = 1; j<=p; j++) {
            if(a[j]==6) {
                flag = 0;break;
            }
        }
        if(i%6==0) flag=0;
        if(flag == 1) {
            b[i] += i*i;
            bb[i] +=b[i]/mod;
            b[i]%=mod;
        }
    }
    int t,n;
    cin>>t;
    while(t--) {
        scanf("%d",&n);
        if(bb[n]==0) printf("%lld\n",b[n]);
        else printf("%lld%.13lld\n",bb[n],b[n]);
    }
    return 0 ;
 }

总结:

晕,,这题debug一年。。思维过程是这样的、、打表的时候是用的int i打的,,所以导致i*i爆了int,,但是没发现,,还以为是最终答案爆了longlong,,开了半个高精度,,发现还是不对,,往前面查,,发现i*i爆了int,于是改成longlong,,再交还是wa,,放弃、、赛后发现高精度写挂了。。低位的数组没有按位补齐。。。然后后来简单证明了一下发现是不会超longlong的(我就说嘛如果是个高精度的坑不可能这么多人当签到题过啊)也就是这题本来就是i*i爆了int而已、、结果越改越挂了。。还有啊之前暑假那个半高精度那个题,之所以没加格式符是因为是对1e18取余,,并且取余之后低位的数组依旧是18位的,,所以不用加。

所以对这个代码中,其实把mod改成1e18,然后把main函数中的格式符去掉,就可以直接ac了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值