#include<bits/stdc++.h> usingnamespace std; int pin[101]; int hash[2000003]; intmain() { int a,b,c,d; int i,j,sum; for(i=1;i<101;i++) pin[i] = i*i; while(scanf("%d%d%d%d", &a,&b,&c,&d)!=EOF) { if( (a>0 && b>0 && c>0 && d>0 )|| (a<0 && b<0 && c<0 && d<0) ) {printf("0\n"); continue; } memset(hash,0,sizeof(hash)); for(i=1;i<=100;i++) for(j=1;j<=100;j++) hash[a * pin[i] + b * pin[j] + 1000000]++; sum = 0; for(i=1;i<=100;i++) for(j=1;j<=100;j++) sum += hash[-(c * pin[i] + d * pin[j]) + 1000000]; printf("%d\n",sum); } return0; }
数组大小可以再优化
经验之谈:
两层循环最多只可能产生10000个不同的结果,开200W的数组将会浪费很多初始化的时间.
所以——
开小数组+处理冲突效果会更好。
解决方案:
#include<bits/stdc++.h> usingnamespace std; #define MAX 50021 int f[MAX], g[MAX]; inthash(int k){ int t = k % MAX; if (t < 0) t += MAX; while (f[t] != 0 && g[t] != k) t = (t + 1) % MAX; return t; } intmain(){ int a, b, c, d, p, i, j, s, n, t[101]; for (i = 1; i <= 100; i++) t[i] = i * i; while (scanf("%d%d%d%d", &a, &b, &c, &d) > 0) { if (a > 0 && b > 0 && c > 0 && d > 0 || a < 0 && b < 0 && c < 0 && d < 0) { printf("0\n"); continue; } memset(f, 0, sizeof(f)); n = 0; for (i = 1; i <= 100; i++) for (j = 1; j <= 100; j++) { s = a * t[i] + b * t[j]; p = hash(s); g[p] = s; f[p]++; } for (i = 1; i <= 100; i++) for (j = 1; j <= 100; j++) { s = -(c * t[i] + d * t[j]); p = hash(s); n += f[p]; } printf("%d\n", n * 16); } return0; }
inlineintELFhash(char *key) { unsignedlong h = 0; unsignedlong g; while( *key ) { h = ( h << 4 ) + *key++; g = h & 0xf0000000L; if( g ) h ^= g >> 24; h &= ~g; } return h; }
int hash[MAXN], count[MAXN]; int maxit, n;
inlinevoidhashit(char *str) { int k,t; while( *str == '0' ) str++; k = ELFhash(str); t = k % MAXN; while( hash[t] != k && hash[t] != -1 ) t = ( t + 10 ) % MAXN; if( hash[t] == -1 ) count[t] = 1, hash[t] = k; elseif( ++count[t] > maxit ) maxit = count[t]; }
vector<char> vec; //存需要排列的字符 voidrev_kangtuo(int k)//输出序号为 k 的字符序列 { int n = vec.size(), len = 0; string ans = ""; k--; // 康托展开从0开始计数 for(int i = 1; i <= n; i++){ int t = k / f[n - i]; // 第 i 位需要 第 t + 1 大的数 k %= f[n - i]; //剩下的几位需要提供的排列数 ans += vec[t] ; // vec[t] 就是第 t + 1 大的数 vec.erase(vec.begin() + t); } cout << ans << '\n'; } 主程序中vec的初始化: for(int i = 1; i <= num; i++) vec.push_back(i + '0'); //num是前面计算好的需要位数