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