Pagini recente » Cod sursa (job #2750449) | Cod sursa (job #2113872) | Cod sursa (job #1624737) | Cod sursa (job #570406) | Cod sursa (job #996530)
Cod sursa(job #996530)
#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 541
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][++H[h][0]]=s;
};
inline long find(long s) {
long h = hash(s);
int 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=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++)
insert(A[i]+A[j]);
};
O << S;
};