Pagini recente » Cod sursa (job #2963302) | Cod sursa (job #1777942) | Cod sursa (job #2442161) | Cod sursa (job #788286) | Cod sursa (job #996545)
Cod sursa(job #996545)
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
using namespace std;
/* Produce some larger tests using:
*
* perl -e '$C = 1024; $L= 600; @A=map{ int(rand($L)+1); } (1..$C); print "$C $L\n"; print join(" ",@A); ' > oite.in
*
* Solve this with a slow std::map in cpp, to produce oite.out and then work on a faster solution
*/
#define MAXC 1024
#define mod 1987
long H[mod+1][MAXC+1];
long c,L,A[MAXC+1];
#define hash(x) ((x)%mod)
inline void insert(long s) {
long h = hash(s);
//H[h][0] += 1;
H[h][ ++H[h][0] ]=s;
};
inline long find(long s) {
long h = hash(s);
long sz = H[h][0];
long count = 0;
for(int i=1;i<sz+1;i++) {
count += (H[h][i] == s);
};
return count;
};
int main() {
int C;
ifstream I("oite.in");
ofstream O("oite.out");
I >> C >> L;
c = 0;
int i,j,k,l;
while(c < C) {
long val;
I >> val;
if(val <= L-3) {
A[c] = val;
c++;
};
};
/*
* |----------- i -----------|
*
* |------j-----|
* |--find(s)---|
*
* |------------|
* |--insert(s)-|
*/
long S = 0;
/*
*
* So first fix 2 of the numbers, so far you have A[i]+A[j]
* then try to find how many pairs in the hash add up to L-(A[i]+A[j]), that's
* the remainder which is needed to reach L.
*
* Inserting is only done with pairs behind the current i in order to assure that the pairs
* found(with find), are different than i,j.
*
* From this point of view I think i is a pivot of sorts.
*
*/
for(i=0;i<mod+1;i++)
H[i][0] = 0;
for(i=1;i<c;i++){
/* the last pair of two numbers A[i] and A[j] */
for(int j=i+1;j<c;j++) {
long lastTwo = L-(A[i]+A[j]);
if(lastTwo > 0)
S += find(lastTwo);
};
/* the first pair of two numbers */
for(int j=0;j<i;j++) {
long ij = A[i] + A[j];
/*
*if(ij==60920516) {
* asm("int $3");
*};
*/
insert(ij);
};
};
O << S;
};