初赛找环,复赛还是找环。初赛没有用到权重(金额),复赛对数据进行加强,同时对相邻两次转账的金额做了限制。
初赛用的单线程,最好成绩:0.2854, 进入了32强。复赛用了多线程,A榜最好成绩:6.1117。多线程负载均衡搞得很差,后面要多学习学习。
初赛最开始用的python,太耗时间了,根本没有办法比赛。这个比赛对于python 和 java选手是不太友好的。初赛后期就转为C++了,刚好可以学习一下C++。
第一次参加这种类型的比赛,总体的感受是收获很多,每天都能学到新的知识。之前没有学过数据结构,这次算是学到了点皮毛。之前写代码,耗时差不多就行,这次算是开了眼,前排大佬们各种骚操作。初赛最后,大佬们直接把线上数据集刺探透了,整个排行榜开始严重内卷。复赛初期,由于线上数据集太弱,又开始卷了。好在官方接受了选手们的意见,增强了数据集。
贴一下初赛的代码,复赛太长了就不贴了。
//
// Created by root on 4/10/20.
//
#include <bits/stdc++.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
using namespace std;
//#define TEST
struct Edge
{
int ida;
int idb;
// int money;
};
struct Slice {
int* arr;
int n;
int* begin() { return arr; }
int* end() { return arr + n; }
};
#define edgesnum 280000
#define nodenum 280000
int feats[edgesnum][3]={0};//保存输入的边,起点id,终点id, 金额
int featscnt=0;
int nodeidmax = 0;
int graph[nodenum][50]={0}; //保存图,图的出度小于50
int graph_size[nodenum]={0};//保存每个点的出度数量
int graphR[nodenum][50]={0};//保存反向图,图的入度小于50
int graphR_size[nodenum]={0};//保存每个点的入度数量
char CID[nodenum][8]={"\0"};
char *(CIDpt[nodenum])={NULL};
int nodetoi[nodenum][50]={0}; // 保存以点j为起点,经过 k到达 i的路径。只用保存k就可以。
int nodetoi_size[nodenum]={0};
int res_cnt[8] = {0,0,0,0,0,0,0,0};
int res3[1000000][3]={0};//保存环3的结果
int res4[1000000][4]={0};
int res5[1000000][5]={0};
int res6[2000000][6]={0};
int res7[3000000][7]={0};//保存环7的结果
char buf[200000000];//保存最后要写入文件的内容
inline int fast_atoi( const char * str )
{
/*将字符串变成整型数*/
int val = 0;
while( *str!=',' ) {
val = val*10 + (*str++ - '0');
}
return val;
}
void load_testdata(string &test_dataf) {
char *buf;
int test_data_size = 0;
int fd = open(test_dataf.c_str(), O_RDONLY);
test_data_size = lseek(fd, 0, SEEK_END);
buf = (char*)mmap(NULL, test_data_size, PROT_READ, MAP_PRIVATE, fd, 0);
char *p = buf;
int temp1 = 0,temp2 = 0;
while((p-buf) < test_data_size) {
temp1 = f