题干:
在国外,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了